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            config_editor_state: Box::new(crate::state::ConfigEditorState::default()),
436            input,
437            results,
438            all_results,
439            results_backup_for_toggle,
440            selected,
441            details,
442            list_state,
443            modal,
444            previous_modal,
445            dry_run,
446            recent,
447            history_state,
448            focus,
449            last_input_change,
450            last_saved_value,
451            recent_path,
452            recent_dirty,
453            latest_query_id,
454            next_query_id,
455            search_cache_query,
456            search_cache_fuzzy,
457            search_cache_results,
458            details_cache,
459            cache_path,
460            cache_dirty,
461            news_read_urls,
462            news_read_path,
463            news_read_dirty,
464            news_read_ids,
465            news_read_ids_path,
466            news_read_ids_dirty,
467            news_items,
468            news_results,
469            news_loading,
470            news_ready,
471            news_selected,
472            news_list_state,
473            news_search_input,
474            news_search_caret,
475            news_search_select_anchor,
476            news_recent,
477            news_recent_path,
478            news_recent_dirty,
479            news_filter_show_arch_news,
480            news_filter_show_advisories,
481            news_filter_show_pkg_updates,
482            news_filter_show_aur_updates,
483            news_filter_show_aur_comments,
484            news_filter_installed_only,
485            news_filter_read_status,
486            news_filter_arch_rect,
487            news_filter_advisory_rect,
488            news_filter_installed_rect,
489            news_filter_updates_rect,
490            news_filter_aur_updates_rect,
491            news_filter_aur_comments_rect,
492            news_filter_read_rect,
493            news_max_age_days,
494            show_news_history_pane,
495            show_news_bookmarks_pane,
496            news_sort_mode,
497            news_bookmarks,
498            news_bookmarks_path,
499            news_bookmarks_dirty,
500            news_content_cache,
501            news_content_cache_path,
502            news_content_cache_dirty,
503            news_content,
504            news_content_loading,
505            news_content_loading_since,
506            news_content_debounce_timer,
507            news_content_scroll,
508            news_feed_path,
509            news_seen_pkg_versions,
510            news_seen_pkg_versions_path,
511            news_seen_pkg_versions_dirty: false,
512            news_seen_aur_comments,
513            news_seen_aur_comments_path,
514            news_seen_aur_comments_dirty: false,
515            news_history_pending,
516            news_history_pending_at,
517            news_history_last_saved,
518            announcements_read_ids,
519            announcement_read_path,
520            announcement_dirty,
521            last_startup_timestamp,
522            last_startup_path,
523            install_list,
524            install_state,
525            remove_list,
526            remove_state,
527            downgrade_list,
528            downgrade_state,
529            install_path,
530            install_dirty,
531            last_install_change,
532            install_list_names,
533            remove_list_names,
534            downgrade_list_names,
535            show_recent_pane,
536            show_install_pane,
537            show_keybinds_footer,
538            pane_find,
539            search_normal_mode,
540            fuzzy_search_enabled,
541            search_caret,
542            search_select_anchor,
543            official_index_path,
544            loading_index,
545            details_focus,
546            scroll_moves,
547            ring_resume_at,
548            need_ring_prefetch,
549            url_button_rect,
550            vt_url_rect,
551            install_import_rect,
552            install_export_rect,
553            arch_status_text,
554            arch_status_rect,
555            arch_status_color,
556            updates_count,
557            updates_list,
558            updates_button_rect,
559            news_button_rect,
560            updates_loading,
561            updates_last_check_authoritative,
562            refresh_updates,
563            pending_updates_modal,
564            faillock_locked,
565            faillock_lockout_until,
566            faillock_remaining_minutes,
567            pkgb_button_rect,
568            pkgb_check_button_rect,
569            pkgb_reload_button_rect,
570            pkgb_visible,
571            pkgb_text,
572            pkgb_package_name,
573            pkgb_reload_requested_at,
574            pkgb_reload_requested_for,
575            pkgb_scroll,
576            pkgb_section_cycle,
577            pkgb_rect,
578            pkgb_run_checks_button_rect,
579            pkgb_check_status,
580            pkgb_check_findings,
581            pkgb_check_raw_results,
582            pkgb_check_missing_tools,
583            pkgb_check_show_raw_output,
584            pkgb_check_scroll,
585            pkgb_check_raw_scroll,
586            pkgb_check_last_package_name,
587            pkgb_check_last_run_at,
588            pkgb_check_last_error,
589            comments_button_rect,
590            comments_visible,
591            comments,
592            comments_package_name,
593            comments_fetched_at,
594            comments_scroll,
595            comments_rect,
596            comments_loading,
597            comments_error,
598            comments_urls,
599            comments_authors,
600            comments_dates,
601            toast_message,
602            toast_expires_at,
603            layout_left_pct,
604            layout_center_pct,
605            layout_right_pct,
606            main_pane_order,
607            vertical_layout_limits,
608            keymap,
609            locale,
610            translations,
611            translations_fallback,
612            results_rect,
613            details_rect,
614            details_scroll,
615            recent_rect,
616            install_rect,
617            downgrade_rect,
618            mouse_disabled_in_details,
619            last_mouse_pos,
620            mouse_capture_enabled,
621            news_rect,
622            news_list_rect,
623            announcement_rect,
624            announcement_urls,
625            pending_announcements,
626            pending_news,
627            pending_startup_setup_steps,
628            trigger_startup_news_fetch,
629            long_run_auth_preflight_warned: false,
630            updates_modal_rect,
631            optional_deps_wizard_rect,
632            optional_deps_modal_rect,
633            system_update_modal_rect,
634            repositories_modal_rect,
635            ssh_setup_copy_key_rect,
636            updates_modal_content_rect,
637            updates_modal_entry_line_starts: Vec::new(),
638            updates_modal_total_lines: 0,
639            updates_modal_pending_g_at: None,
640            help_scroll,
641            help_rect,
642            preflight_tab_rects,
643            preflight_content_rect,
644            sort_mode,
645            installed_packages_mode: crate::state::types::InstalledPackagesMode::default(),
646            sort_menu_open,
647            sort_button_rect,
648            news_age_button_rect,
649            sort_menu_rect,
650            sort_menu_auto_close_at,
651            sort_cache_repo_name,
652            sort_cache_aur_popularity,
653            sort_cache_signature,
654            options_menu_open,
655            options_button_rect,
656            options_menu_rect,
657            panels_menu_open,
658            panels_button_rect,
659            panels_menu_rect,
660            config_menu_open,
661            artix_filter_menu_open,
662            artix_filter_menu_rect,
663            custom_repos_filter_menu_open,
664            custom_repos_filter_menu_rect,
665            config_button_rect,
666            config_menu_rect,
667            collapsed_menu_open,
668            collapsed_menu_button_rect,
669            collapsed_menu_rect,
670            installed_only_mode,
671            right_pane_focus,
672            package_marker,
673            results_filter_show_aur,
674            results_filter_show_core,
675            results_filter_show_extra,
676            results_filter_show_multilib,
677            results_filter_show_eos,
678            results_filter_show_cachyos,
679            results_filter_show_artix,
680            results_filter_show_artix_omniverse,
681            results_filter_show_artix_universe,
682            results_filter_show_artix_lib32,
683            results_filter_show_artix_galaxy,
684            results_filter_show_artix_world,
685            results_filter_show_artix_system,
686            results_filter_show_blackarch,
687            results_filter_show_manjaro,
688            repo_results_filter_by_name: HashMap::new(),
689            results_filter_dynamic: HashMap::new(),
690            results_filter_aur_rect,
691            results_filter_core_rect,
692            results_filter_extra_rect,
693            results_filter_multilib_rect,
694            results_filter_eos_rect,
695            results_filter_cachyos_rect,
696            results_filter_artix_rect,
697            results_filter_artix_omniverse_rect,
698            results_filter_artix_universe_rect,
699            results_filter_artix_lib32_rect,
700            results_filter_artix_galaxy_rect,
701            results_filter_artix_world_rect,
702            results_filter_artix_system_rect,
703            results_filter_blackarch_rect,
704            results_filter_manjaro_rect,
705            results_filter_custom_repos_rect: None,
706            fuzzy_indicator_rect: None,
707            refresh_installed_until,
708            next_installed_refresh_at,
709            pending_install_names,
710            pending_remove_names,
711            install_list_deps,
712            remove_preflight_summary,
713            remove_cascade_mode,
714            deps_resolving,
715            deps_cache_path,
716            deps_cache_dirty,
717            install_list_files,
718            files_resolving,
719            files_cache_path,
720            files_cache_dirty,
721            install_list_services,
722            services_resolving,
723            services_cache_path,
724            services_cache_dirty,
725            service_resolve_now,
726            active_service_request,
727            next_service_request_id,
728            services_pending_signature,
729            pending_service_plan,
730            install_list_sandbox,
731            sandbox_resolving,
732            sandbox_cache_path,
733            sandbox_cache_dirty,
734            preflight_summary_items,
735            preflight_deps_items,
736            preflight_files_items,
737            preflight_services_items,
738            preflight_sandbox_items,
739            preflight_summary_resolving,
740            preflight_deps_resolving,
741            preflight_files_resolving,
742            preflight_services_resolving,
743            preflight_sandbox_resolving,
744            last_logged_preflight_deps_state,
745            preflight_cancelled,
746            pending_aur_vote_intent: None,
747            pending_aur_vote_request: None,
748            aur_vote_state_by_pkgbase,
749            aur_vote_state_path,
750            aur_vote_state_dirty: false,
751            aur_vote_state_lookup_supported: true,
752            pending_aur_vote_state_request: None,
753            pending_executor_request: None,
754            pending_exec_header_chips: None,
755            pending_post_summary_items: None,
756            pending_custom_command: None,
757            pending_update_commands: None,
758            pending_repo_apply_commands: None,
759            pending_repo_apply_summary: None,
760            pending_repo_apply_overlap_check: None,
761            pending_repositories_modal_resume: None,
762            pending_foreign_migrate_commands: None,
763            pending_foreign_migrate_summary: None,
764            skip_aur_repo_dup_warning_once: false,
765            pending_aur_update_command: None,
766            pending_executor_password: None,
767            pending_file_sync_result: None,
768            pending_aur_ssh_help_check_result: None,
769            aur_ssh_help_ready: None,
770        }
771    }
772}