Skip to main content

pacsea/state/app_state/
default_impl.rs

1//! Default implementation for `AppState`.
2
3use std::collections::HashMap;
4
5use super::AppState;
6use super::defaults;
7use super::defaults_cache;
8
9impl Default for AppState {
10    /// What: Construct a default, empty [`AppState`] with initialized paths, selection states, and timers.
11    ///
12    /// Inputs:
13    /// - None.
14    ///
15    /// Output:
16    /// - Returns an `AppState` instance with sensible defaults for all fields.
17    ///
18    /// Details:
19    /// - Delegates initialization to helper functions that group related fields logically.
20    /// - Initializes paths for persisted data (recent searches, cache, news, install list, etc.) under the configured lists directory.
21    /// - Sets selection indices to zero, result buffers to empty, and UI flags to default visibility states.
22    /// - All repository filters default to showing everything.
23    /// - Initializes timers, scroll positions, and modal states to their default values.
24    #[allow(clippy::too_many_lines)] // Function has 652 lines - initializes large AppState struct with many fields, delegating to helper functions for logical grouping; refactoring would reduce readability
25    fn default() -> Self {
26        let (
27            recent_path,
28            cache_path,
29            news_read_path,
30            news_read_ids_path,
31            install_path,
32            official_index_path,
33            deps_cache_path,
34            files_cache_path,
35            services_cache_path,
36            announcement_read_path,
37            news_recent_path,
38            news_bookmarks_path,
39        ) = defaults::default_paths();
40        let news_feed_path = crate::theme::lists_dir().join("news_feed.json");
41        let news_content_cache_path = crate::theme::lists_dir().join("news_content_cache.json");
42        let news_seen_pkg_versions_path =
43            crate::theme::lists_dir().join("news_seen_pkg_updates.json");
44        let news_seen_aur_comments_path =
45            crate::theme::lists_dir().join("news_seen_aur_comments.json");
46        let news_seen_pkg_versions: HashMap<String, String> =
47            std::fs::read_to_string(&news_seen_pkg_versions_path)
48                .ok()
49                .and_then(|s| serde_json::from_str(&s).ok())
50                .unwrap_or_default();
51        let news_seen_aur_comments: HashMap<String, String> =
52            std::fs::read_to_string(&news_seen_aur_comments_path)
53                .ok()
54                .and_then(|s| serde_json::from_str(&s).ok())
55                .unwrap_or_default();
56        let aur_vote_state_path = crate::theme::lists_dir().join("aur_vote_state.json");
57        let aur_vote_state_by_pkgbase: HashMap<String, crate::state::app_state::AurVoteStateUi> =
58            std::fs::read_to_string(&aur_vote_state_path)
59                .ok()
60                .and_then(|s| serde_json::from_str::<HashMap<String, bool>>(&s).ok())
61                .map(|persisted| {
62                    persisted
63                        .into_iter()
64                        .map(|(pkgbase, voted)| {
65                            let state = if voted {
66                                crate::state::app_state::AurVoteStateUi::Voted
67                            } else {
68                                crate::state::app_state::AurVoteStateUi::NotVoted
69                            };
70                            (pkgbase, state)
71                        })
72                        .collect()
73                })
74                .unwrap_or_default();
75
76        // Load last startup timestamp and save current timestamp
77        let last_startup_path = crate::theme::lists_dir().join("last_startup.txt");
78        let last_startup_timestamp = std::fs::read_to_string(&last_startup_path)
79            .ok()
80            .map(|s| s.trim().to_string())
81            .filter(|s| !s.is_empty());
82        // Save current timestamp for next startup
83        let current_timestamp = chrono::Local::now().format("%Y%m%d:%H%M%S").to_string();
84        let _ = std::fs::write(&last_startup_path, &current_timestamp);
85        tracing::info!(
86            previous = ?last_startup_timestamp,
87            current = %current_timestamp,
88            "startup timestamp tracking"
89        );
90
91        let (
92            results_filter_show_aur,
93            results_filter_show_core,
94            results_filter_show_extra,
95            results_filter_show_multilib,
96            results_filter_show_eos,
97            results_filter_show_cachyos,
98            results_filter_show_artix,
99            results_filter_show_artix_omniverse,
100            results_filter_show_artix_universe,
101            results_filter_show_artix_lib32,
102            results_filter_show_artix_galaxy,
103            results_filter_show_artix_world,
104            results_filter_show_artix_system,
105            results_filter_show_blackarch,
106            results_filter_show_manjaro,
107            filter_rects,
108        ) = defaults::default_filters();
109        let [
110            results_filter_aur_rect,
111            results_filter_core_rect,
112            results_filter_extra_rect,
113            results_filter_multilib_rect,
114            results_filter_eos_rect,
115            results_filter_cachyos_rect,
116            results_filter_artix_rect,
117            results_filter_artix_omniverse_rect,
118            results_filter_artix_universe_rect,
119            results_filter_artix_lib32_rect,
120            results_filter_artix_galaxy_rect,
121            results_filter_artix_world_rect,
122            results_filter_artix_system_rect,
123            results_filter_blackarch_rect,
124            results_filter_manjaro_rect,
125        ] = filter_rects;
126
127        let (
128            input,
129            results,
130            all_results,
131            results_backup_for_toggle,
132            selected,
133            details,
134            list_state,
135            modal,
136            previous_modal,
137            dry_run,
138            focus,
139            last_input_change,
140            last_saved_value,
141            latest_query_id,
142            next_query_id,
143            search_cache_query,
144            search_cache_fuzzy,
145            search_cache_results,
146        ) = defaults::default_search_state();
147
148        let app_mode = defaults::default_app_mode();
149
150        let (
151            news_items,
152            news_results,
153            news_loading,
154            news_ready,
155            news_selected,
156            news_list_state,
157            news_search_input,
158            news_search_caret,
159            news_search_select_anchor,
160            news_recent,
161            news_recent_path,
162            news_recent_dirty,
163            news_filter_show_arch_news,
164            news_filter_show_advisories,
165            news_filter_show_pkg_updates,
166            news_filter_show_aur_updates,
167            news_filter_show_aur_comments,
168            news_filter_installed_only,
169            news_filter_read_status,
170            news_filter_arch_rect,
171            news_filter_advisory_rect,
172            news_filter_installed_rect,
173            news_filter_updates_rect,
174            news_filter_aur_updates_rect,
175            news_filter_aur_comments_rect,
176            news_filter_read_rect,
177            news_max_age_days,
178            show_news_history_pane,
179            show_news_bookmarks_pane,
180            news_sort_mode,
181            news_bookmarks,
182            news_bookmarks_path,
183            news_bookmarks_dirty,
184            news_content_cache,
185            news_content_cache_path,
186            news_content_cache_dirty,
187            news_content,
188            news_content_loading,
189            news_content_loading_since,
190            news_content_debounce_timer,
191            news_content_scroll,
192            news_history_pending,
193            news_history_pending_at,
194            news_history_last_saved,
195        ) = defaults::default_news_feed_state(
196            news_recent_path,
197            news_bookmarks_path,
198            &news_feed_path,
199            news_content_cache_path,
200        );
201
202        let (recent, history_state, recent_path, recent_dirty) =
203            defaults::default_recent_state(recent_path);
204
205        let (details_cache, cache_path, cache_dirty) =
206            defaults::default_details_cache_state(cache_path);
207
208        let (news_read_urls, news_read_path, news_read_dirty) =
209            defaults::default_news_state(news_read_path);
210
211        let (news_read_ids, news_read_ids_path, news_read_ids_dirty) =
212            defaults::default_news_read_ids_state(news_read_ids_path);
213
214        let (announcements_read_ids, announcement_read_path, announcement_dirty) =
215            defaults::default_announcement_state(announcement_read_path);
216
217        let (
218            install_list,
219            install_state,
220            remove_list,
221            remove_state,
222            downgrade_list,
223            downgrade_state,
224            install_path,
225            install_dirty,
226            last_install_change,
227            install_list_names,
228            remove_list_names,
229            downgrade_list_names,
230        ) = defaults::default_install_lists_state(install_path);
231
232        let (show_recent_pane, show_install_pane, show_keybinds_footer, pane_find) =
233            defaults::default_ui_visibility_state();
234
235        let (search_normal_mode, fuzzy_search_enabled, search_caret, search_select_anchor) =
236            defaults::default_search_input_state();
237
238        let (official_index_path, loading_index, details_focus) =
239            defaults::default_index_state(official_index_path);
240
241        let (scroll_moves, ring_resume_at, need_ring_prefetch) =
242            defaults::default_scroll_prefetch_state();
243
244        let (
245            url_button_rect,
246            vt_url_rect,
247            install_import_rect,
248            install_export_rect,
249            arch_status_text,
250            arch_status_rect,
251            arch_status_color,
252            updates_count,
253            updates_list,
254            updates_button_rect,
255            news_button_rect,
256            updates_loading,
257            updates_last_check_authoritative,
258            refresh_updates,
259            pending_updates_modal,
260            faillock_locked,
261            faillock_lockout_until,
262            faillock_remaining_minutes,
263        ) = defaults::default_clickable_rects_state();
264
265        let (
266            pkgb_button_rect,
267            pkgb_check_button_rect,
268            pkgb_reload_button_rect,
269            pkgb_visible,
270            pkgb_text,
271            pkgb_package_name,
272            pkgb_reload_requested_at,
273            pkgb_reload_requested_for,
274            pkgb_scroll,
275            pkgb_section_cycle,
276            pkgb_rect,
277            pkgb_run_checks_button_rect,
278            pkgb_check_status,
279            pkgb_check_findings,
280            pkgb_check_raw_results,
281            pkgb_check_missing_tools,
282            pkgb_check_show_raw_output,
283            pkgb_check_scroll,
284            pkgb_check_raw_scroll,
285            pkgb_check_last_package_name,
286            pkgb_check_last_run_at,
287            pkgb_check_last_error,
288        ) = defaults::default_pkgbuild_state();
289
290        let (
291            comments_button_rect,
292            comments_visible,
293            comments,
294            comments_package_name,
295            comments_fetched_at,
296            comments_scroll,
297            comments_rect,
298            comments_loading,
299            comments_error,
300            comments_urls,
301            comments_authors,
302            comments_dates,
303        ) = defaults::default_comments_state();
304
305        let (toast_message, toast_expires_at) = defaults::default_toast_state();
306
307        let (
308            layout_left_pct,
309            layout_center_pct,
310            layout_right_pct,
311            keymap,
312            locale,
313            translations,
314            translations_fallback,
315            main_pane_order,
316            vertical_layout_limits,
317        ) = defaults::default_settings_state();
318
319        let (
320            results_rect,
321            details_rect,
322            details_scroll,
323            recent_rect,
324            install_rect,
325            downgrade_rect,
326            mouse_disabled_in_details,
327            last_mouse_pos,
328            mouse_capture_enabled,
329        ) = defaults::default_mouse_hit_test_state();
330
331        let (
332            news_rect,
333            news_list_rect,
334            announcement_rect,
335            announcement_urls,
336            pending_announcements,
337            pending_news,
338            pending_startup_setup_steps,
339            trigger_startup_news_fetch,
340            updates_modal_rect,
341            optional_deps_wizard_rect,
342            optional_deps_modal_rect,
343            system_update_modal_rect,
344            repositories_modal_rect,
345            ssh_setup_copy_key_rect,
346            updates_modal_content_rect,
347            help_scroll,
348            help_rect,
349            preflight_tab_rects,
350            preflight_content_rect,
351        ) = defaults::default_modal_rects_state();
352
353        let (
354            sort_mode,
355            sort_menu_open,
356            sort_button_rect,
357            news_age_button_rect,
358            sort_menu_rect,
359            sort_menu_auto_close_at,
360            options_menu_open,
361            options_button_rect,
362            options_menu_rect,
363            panels_menu_open,
364            panels_button_rect,
365            panels_menu_rect,
366            config_menu_open,
367            artix_filter_menu_open,
368            artix_filter_menu_rect,
369            custom_repos_filter_menu_open,
370            custom_repos_filter_menu_rect,
371            config_button_rect,
372            config_menu_rect,
373            collapsed_menu_open,
374            collapsed_menu_button_rect,
375            collapsed_menu_rect,
376            sort_cache_repo_name,
377            sort_cache_aur_popularity,
378            sort_cache_signature,
379        ) = defaults::default_sorting_menus_state();
380
381        let (installed_only_mode, right_pane_focus, package_marker) =
382            defaults::default_results_mode_state();
383
384        let (
385            refresh_installed_until,
386            next_installed_refresh_at,
387            pending_install_names,
388            pending_remove_names,
389        ) = defaults_cache::default_cache_refresh_state();
390
391        let (
392            install_list_deps,
393            remove_preflight_summary,
394            remove_cascade_mode,
395            deps_resolving,
396            deps_cache_path,
397            deps_cache_dirty,
398        ) = defaults_cache::default_deps_cache_state(deps_cache_path);
399
400        let (install_list_files, files_resolving, files_cache_path, files_cache_dirty) =
401            defaults_cache::default_files_cache_state(files_cache_path);
402
403        let (
404            install_list_services,
405            services_resolving,
406            services_cache_path,
407            services_cache_dirty,
408            service_resolve_now,
409            active_service_request,
410            next_service_request_id,
411            services_pending_signature,
412            pending_service_plan,
413        ) = defaults_cache::default_services_cache_state(services_cache_path);
414
415        let (install_list_sandbox, sandbox_resolving, sandbox_cache_path, sandbox_cache_dirty) =
416            defaults_cache::default_sandbox_cache_state();
417
418        let (
419            preflight_summary_items,
420            preflight_deps_items,
421            preflight_files_items,
422            preflight_services_items,
423            preflight_sandbox_items,
424            preflight_summary_resolving,
425            preflight_deps_resolving,
426            preflight_files_resolving,
427            preflight_services_resolving,
428            preflight_sandbox_resolving,
429            last_logged_preflight_deps_state,
430            preflight_cancelled,
431        ) = defaults_cache::default_preflight_state();
432
433        Self {
434            app_mode,
435            input,
436            results,
437            all_results,
438            results_backup_for_toggle,
439            selected,
440            details,
441            list_state,
442            modal,
443            previous_modal,
444            dry_run,
445            recent,
446            history_state,
447            focus,
448            last_input_change,
449            last_saved_value,
450            recent_path,
451            recent_dirty,
452            latest_query_id,
453            next_query_id,
454            search_cache_query,
455            search_cache_fuzzy,
456            search_cache_results,
457            details_cache,
458            cache_path,
459            cache_dirty,
460            news_read_urls,
461            news_read_path,
462            news_read_dirty,
463            news_read_ids,
464            news_read_ids_path,
465            news_read_ids_dirty,
466            news_items,
467            news_results,
468            news_loading,
469            news_ready,
470            news_selected,
471            news_list_state,
472            news_search_input,
473            news_search_caret,
474            news_search_select_anchor,
475            news_recent,
476            news_recent_path,
477            news_recent_dirty,
478            news_filter_show_arch_news,
479            news_filter_show_advisories,
480            news_filter_show_pkg_updates,
481            news_filter_show_aur_updates,
482            news_filter_show_aur_comments,
483            news_filter_installed_only,
484            news_filter_read_status,
485            news_filter_arch_rect,
486            news_filter_advisory_rect,
487            news_filter_installed_rect,
488            news_filter_updates_rect,
489            news_filter_aur_updates_rect,
490            news_filter_aur_comments_rect,
491            news_filter_read_rect,
492            news_max_age_days,
493            show_news_history_pane,
494            show_news_bookmarks_pane,
495            news_sort_mode,
496            news_bookmarks,
497            news_bookmarks_path,
498            news_bookmarks_dirty,
499            news_content_cache,
500            news_content_cache_path,
501            news_content_cache_dirty,
502            news_content,
503            news_content_loading,
504            news_content_loading_since,
505            news_content_debounce_timer,
506            news_content_scroll,
507            news_feed_path,
508            news_seen_pkg_versions,
509            news_seen_pkg_versions_path,
510            news_seen_pkg_versions_dirty: false,
511            news_seen_aur_comments,
512            news_seen_aur_comments_path,
513            news_seen_aur_comments_dirty: false,
514            news_history_pending,
515            news_history_pending_at,
516            news_history_last_saved,
517            announcements_read_ids,
518            announcement_read_path,
519            announcement_dirty,
520            last_startup_timestamp,
521            last_startup_path,
522            install_list,
523            install_state,
524            remove_list,
525            remove_state,
526            downgrade_list,
527            downgrade_state,
528            install_path,
529            install_dirty,
530            last_install_change,
531            install_list_names,
532            remove_list_names,
533            downgrade_list_names,
534            show_recent_pane,
535            show_install_pane,
536            show_keybinds_footer,
537            pane_find,
538            search_normal_mode,
539            fuzzy_search_enabled,
540            search_caret,
541            search_select_anchor,
542            official_index_path,
543            loading_index,
544            details_focus,
545            scroll_moves,
546            ring_resume_at,
547            need_ring_prefetch,
548            url_button_rect,
549            vt_url_rect,
550            install_import_rect,
551            install_export_rect,
552            arch_status_text,
553            arch_status_rect,
554            arch_status_color,
555            updates_count,
556            updates_list,
557            updates_button_rect,
558            news_button_rect,
559            updates_loading,
560            updates_last_check_authoritative,
561            refresh_updates,
562            pending_updates_modal,
563            faillock_locked,
564            faillock_lockout_until,
565            faillock_remaining_minutes,
566            pkgb_button_rect,
567            pkgb_check_button_rect,
568            pkgb_reload_button_rect,
569            pkgb_visible,
570            pkgb_text,
571            pkgb_package_name,
572            pkgb_reload_requested_at,
573            pkgb_reload_requested_for,
574            pkgb_scroll,
575            pkgb_section_cycle,
576            pkgb_rect,
577            pkgb_run_checks_button_rect,
578            pkgb_check_status,
579            pkgb_check_findings,
580            pkgb_check_raw_results,
581            pkgb_check_missing_tools,
582            pkgb_check_show_raw_output,
583            pkgb_check_scroll,
584            pkgb_check_raw_scroll,
585            pkgb_check_last_package_name,
586            pkgb_check_last_run_at,
587            pkgb_check_last_error,
588            comments_button_rect,
589            comments_visible,
590            comments,
591            comments_package_name,
592            comments_fetched_at,
593            comments_scroll,
594            comments_rect,
595            comments_loading,
596            comments_error,
597            comments_urls,
598            comments_authors,
599            comments_dates,
600            toast_message,
601            toast_expires_at,
602            layout_left_pct,
603            layout_center_pct,
604            layout_right_pct,
605            main_pane_order,
606            vertical_layout_limits,
607            keymap,
608            locale,
609            translations,
610            translations_fallback,
611            results_rect,
612            details_rect,
613            details_scroll,
614            recent_rect,
615            install_rect,
616            downgrade_rect,
617            mouse_disabled_in_details,
618            last_mouse_pos,
619            mouse_capture_enabled,
620            news_rect,
621            news_list_rect,
622            announcement_rect,
623            announcement_urls,
624            pending_announcements,
625            pending_news,
626            pending_startup_setup_steps,
627            trigger_startup_news_fetch,
628            long_run_auth_preflight_warned: false,
629            updates_modal_rect,
630            optional_deps_wizard_rect,
631            optional_deps_modal_rect,
632            system_update_modal_rect,
633            repositories_modal_rect,
634            ssh_setup_copy_key_rect,
635            updates_modal_content_rect,
636            updates_modal_entry_line_starts: Vec::new(),
637            updates_modal_total_lines: 0,
638            updates_modal_pending_g_at: None,
639            help_scroll,
640            help_rect,
641            preflight_tab_rects,
642            preflight_content_rect,
643            sort_mode,
644            installed_packages_mode: crate::state::types::InstalledPackagesMode::default(),
645            sort_menu_open,
646            sort_button_rect,
647            news_age_button_rect,
648            sort_menu_rect,
649            sort_menu_auto_close_at,
650            sort_cache_repo_name,
651            sort_cache_aur_popularity,
652            sort_cache_signature,
653            options_menu_open,
654            options_button_rect,
655            options_menu_rect,
656            panels_menu_open,
657            panels_button_rect,
658            panels_menu_rect,
659            config_menu_open,
660            artix_filter_menu_open,
661            artix_filter_menu_rect,
662            custom_repos_filter_menu_open,
663            custom_repos_filter_menu_rect,
664            config_button_rect,
665            config_menu_rect,
666            collapsed_menu_open,
667            collapsed_menu_button_rect,
668            collapsed_menu_rect,
669            installed_only_mode,
670            right_pane_focus,
671            package_marker,
672            results_filter_show_aur,
673            results_filter_show_core,
674            results_filter_show_extra,
675            results_filter_show_multilib,
676            results_filter_show_eos,
677            results_filter_show_cachyos,
678            results_filter_show_artix,
679            results_filter_show_artix_omniverse,
680            results_filter_show_artix_universe,
681            results_filter_show_artix_lib32,
682            results_filter_show_artix_galaxy,
683            results_filter_show_artix_world,
684            results_filter_show_artix_system,
685            results_filter_show_blackarch,
686            results_filter_show_manjaro,
687            repo_results_filter_by_name: HashMap::new(),
688            results_filter_dynamic: HashMap::new(),
689            results_filter_aur_rect,
690            results_filter_core_rect,
691            results_filter_extra_rect,
692            results_filter_multilib_rect,
693            results_filter_eos_rect,
694            results_filter_cachyos_rect,
695            results_filter_artix_rect,
696            results_filter_artix_omniverse_rect,
697            results_filter_artix_universe_rect,
698            results_filter_artix_lib32_rect,
699            results_filter_artix_galaxy_rect,
700            results_filter_artix_world_rect,
701            results_filter_artix_system_rect,
702            results_filter_blackarch_rect,
703            results_filter_manjaro_rect,
704            results_filter_custom_repos_rect: None,
705            fuzzy_indicator_rect: None,
706            refresh_installed_until,
707            next_installed_refresh_at,
708            pending_install_names,
709            pending_remove_names,
710            install_list_deps,
711            remove_preflight_summary,
712            remove_cascade_mode,
713            deps_resolving,
714            deps_cache_path,
715            deps_cache_dirty,
716            install_list_files,
717            files_resolving,
718            files_cache_path,
719            files_cache_dirty,
720            install_list_services,
721            services_resolving,
722            services_cache_path,
723            services_cache_dirty,
724            service_resolve_now,
725            active_service_request,
726            next_service_request_id,
727            services_pending_signature,
728            pending_service_plan,
729            install_list_sandbox,
730            sandbox_resolving,
731            sandbox_cache_path,
732            sandbox_cache_dirty,
733            preflight_summary_items,
734            preflight_deps_items,
735            preflight_files_items,
736            preflight_services_items,
737            preflight_sandbox_items,
738            preflight_summary_resolving,
739            preflight_deps_resolving,
740            preflight_files_resolving,
741            preflight_services_resolving,
742            preflight_sandbox_resolving,
743            last_logged_preflight_deps_state,
744            preflight_cancelled,
745            pending_aur_vote_intent: None,
746            pending_aur_vote_request: None,
747            aur_vote_state_by_pkgbase,
748            aur_vote_state_path,
749            aur_vote_state_dirty: false,
750            aur_vote_state_lookup_supported: true,
751            pending_aur_vote_state_request: None,
752            pending_executor_request: None,
753            pending_exec_header_chips: None,
754            pending_post_summary_items: None,
755            pending_custom_command: None,
756            pending_update_commands: None,
757            pending_repo_apply_commands: None,
758            pending_repo_apply_summary: None,
759            pending_repo_apply_overlap_check: None,
760            pending_repositories_modal_resume: None,
761            pending_foreign_migrate_commands: None,
762            pending_foreign_migrate_summary: None,
763            skip_aur_repo_dup_warning_once: false,
764            pending_aur_update_command: None,
765            pending_executor_password: None,
766            pending_file_sync_result: None,
767            pending_aur_ssh_help_check_result: None,
768            aur_ssh_help_ready: None,
769        }
770    }
771}