Skip to main content

mimick/settings_window/
behavior.rs

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}