1use adw::prelude::*;
2use libadwaita as adw;
3
4pub struct BehaviorWidgets {
5 pub startup_row: adw::SwitchRow,
6 pub background_sync_row: adw::SwitchRow,
7 pub metered_row: adw::SwitchRow,
8 pub battery_row: adw::SwitchRow,
9 pub notifications_row: adw::SwitchRow,
10 pub library_view_row: adw::SwitchRow,
11 pub catchup_row: adw::ComboRow,
12 pub concurrency_row: adw::SpinRow,
13 pub xmp_sidecar_row: adw::SwitchRow,
14 pub quiet_hours_row: adw::SwitchRow,
15 pub quiet_start_row: adw::SpinRow,
16 pub quiet_end_row: adw::SpinRow,
17}
18
19pub fn build_behavior_group(settings_page: &adw::PreferencesPage) -> BehaviorWidgets {
20 let behavior_group = adw::PreferencesGroup::builder().title("Behavior").build();
21 settings_page.add(&behavior_group);
22
23 let (
24 startup_row,
25 background_sync_row,
26 metered_row,
27 battery_row,
28 notifications_row,
29 library_view_row,
30 ) = add_toggle_rows(&behavior_group);
31 let (catchup_row, concurrency_row, xmp_sidecar_row) = add_upload_rows(&behavior_group);
32 let (quiet_hours_row, quiet_start_row, quiet_end_row) = add_quiet_hours_rows(&behavior_group);
33
34 BehaviorWidgets {
35 startup_row,
36 background_sync_row,
37 metered_row,
38 battery_row,
39 notifications_row,
40 library_view_row,
41 catchup_row,
42 concurrency_row,
43 xmp_sidecar_row,
44 quiet_hours_row,
45 quiet_start_row,
46 quiet_end_row,
47 }
48}
49
50fn add_toggle_rows(
51 group: &adw::PreferencesGroup,
52) -> (
53 adw::SwitchRow,
54 adw::SwitchRow,
55 adw::SwitchRow,
56 adw::SwitchRow,
57 adw::SwitchRow,
58 adw::SwitchRow,
59) {
60 let startup = add_switch(group, "Run on Startup", "Start Mimick at login.");
61 let background = add_switch(
62 group,
63 "Background Sync",
64 "Watch folders in the background after launch.",
65 );
66 let metered = add_switch(
67 group,
68 "Pause on Metered Network",
69 "Pause uploads on metered connections.",
70 );
71 let battery = add_switch(
72 group,
73 "Pause on Battery Power",
74 "Pause uploads while on battery.",
75 );
76 let notifications = add_switch(
77 group,
78 "Enable Notifications",
79 "Desktop notifications for sync events.",
80 );
81 let library = add_switch(
82 group,
83 "Enable Library View",
84 "In-app library browser. Requires restart.",
85 );
86 (
87 startup,
88 background,
89 metered,
90 battery,
91 notifications,
92 library,
93 )
94}
95
96fn add_upload_rows(group: &adw::PreferencesGroup) -> (adw::ComboRow, adw::SpinRow, adw::SwitchRow) {
97 let catchup = add_catchup_row(group);
98 let concurrency = add_spin(
99 group,
100 "Upload Workers",
101 "Parallel uploads. More = faster batches.",
102 gtk::Adjustment::new(3.0, 1.0, 10.0, 1.0, 1.0, 0.0),
103 );
104 let xmp = add_switch(
105 group,
106 "Upload XMP Sidecars",
107 "Attach .xmp sidecars with uploads.",
108 );
109 (catchup, concurrency, xmp)
110}
111
112fn add_quiet_hours_rows(
113 group: &adw::PreferencesGroup,
114) -> (adw::SwitchRow, adw::SpinRow, adw::SpinRow) {
115 let toggle = add_switch(group, "Quiet Hours", "Pause uploads on a nightly schedule.");
116 let start = add_spin(
117 group,
118 "Quiet Hours Start (hour, local)",
119 "",
120 gtk::Adjustment::new(22.0, 0.0, 23.0, 1.0, 1.0, 0.0),
121 );
122 let end = add_spin(
123 group,
124 "Quiet Hours End (hour, local)",
125 "",
126 gtk::Adjustment::new(7.0, 0.0, 23.0, 1.0, 1.0, 0.0),
127 );
128 (toggle, start, end)
129}
130
131fn add_switch(group: &adw::PreferencesGroup, title: &str, subtitle: &str) -> adw::SwitchRow {
132 let row = adw::SwitchRow::builder()
133 .title(title)
134 .subtitle(subtitle)
135 .build();
136 group.add(&row);
137 row
138}
139
140fn add_catchup_row(group: &adw::PreferencesGroup) -> adw::ComboRow {
141 let model = gtk::StringList::new(&["Full Scan", "Recent Only (7d)", "New Files Only"]);
142 let row = adw::ComboRow::builder()
143 .title("Default Startup Catch-up Mode")
144 .subtitle("Used when a folder has no override.")
145 .model(&model)
146 .build();
147 group.add(&row);
148 row
149}
150
151fn add_spin(
152 group: &adw::PreferencesGroup,
153 title: &str,
154 subtitle: &str,
155 adjustment: gtk::Adjustment,
156) -> adw::SpinRow {
157 let mut builder = adw::SpinRow::builder().title(title).adjustment(&adjustment);
158 if !subtitle.is_empty() {
159 builder = builder.subtitle(subtitle);
160 }
161 let row = builder.build();
162 group.add(&row);
163 row
164}