a lightweight, interval-based utility to combat digital strain through "Ma" (intentional pauses) for the eyes and body.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: require pw verification to disabled enforced mode

+54 -5
+34
src/settings/mod.rs
··· 175 175 }); 176 176 } 177 177 178 + // Enforced mode toggle — require password verification to turn off 179 + // when a password has been set. 180 + { 181 + let win_em = self.window.clone_strong(); 182 + let cfg_arc_em = cfg_arc.clone(); 183 + self.window.on_enforced_mode_toggled(move |_checked| { 184 + // The toggle was turned off with a password set. 185 + // Open the password window for verification. 186 + let hash = cfg_arc_em.lock().unwrap().enforced.password_hash.clone(); 187 + match PasswordSetupWindow::new() { 188 + Ok(pw) => { 189 + pw.set_verify_mode(true); 190 + let pw_cancel = pw.clone_strong(); 191 + pw.on_cancel_clicked(move || { 192 + pw_cancel.hide().unwrap_or_default(); 193 + }); 194 + let pw_submit = pw.clone_strong(); 195 + let hash_clone = hash.clone(); 196 + let win_disable = win_em.clone_strong(); 197 + pw.on_submit_clicked(move |password| { 198 + if password::verify_password(password.as_str(), &hash_clone) { 199 + win_disable.set_enforced_mode(false); 200 + pw_submit.hide().unwrap_or_default(); 201 + } else { 202 + pw_submit.set_error_text("Incorrect password.".into()); 203 + } 204 + }); 205 + pw.show().unwrap_or_default(); 206 + } 207 + Err(e) => log::warn!("Failed to create password window: {e}"), 208 + } 209 + }); 210 + } 211 + 178 212 self.window.show().unwrap_or_default(); 179 213 // Force the window to its intended size after the first show(). On 180 214 // Linux/X11 the WM may not honour with_inner_size during initial window
+8 -4
ui/password.slint
··· 6 6 import "../assets/fonts/Nunito-Bold.ttf"; 7 7 8 8 export component PasswordSetupWindow inherits Window { 9 - title: "ioma — Set Emergency Password"; 9 + title: root.verify-mode ? "ioma — Verify Password" : "ioma — Set Emergency Password"; 10 10 width: 420px; 11 11 height: 260px; 12 12 default-font-family: "Nunito"; 13 13 14 + in property <bool> verify-mode: false; 14 15 in-out property <string> error-text: ""; 15 16 16 17 callback submit-clicked(string /* password */); ··· 22 23 spacing: 12px; 23 24 24 25 Text { 25 - text: "Have someone you trust set an emergency unlock password."; 26 + text: root.verify-mode 27 + ? "Enter the emergency unlock password to turn off enforced mode." 28 + : "Have someone you trust set an emergency unlock password."; 26 29 wrap: word-wrap; 27 30 color: #888888; 28 31 font-size: Theme.font_body; ··· 36 39 confirm-field := LineEdit { 37 40 placeholder-text: "Confirm password"; 38 41 input-type: password; 42 + visible: !root.verify-mode; 39 43 } 40 44 41 45 if error-text != "" : Text { ··· 53 57 clicked => { root.cancel-clicked(); } 54 58 } 55 59 Button { 56 - text: "Set Password"; 60 + text: root.verify-mode ? "Verify" : "Set Password"; 57 61 clicked => { 58 62 if password-field.text == "" { 59 63 root.error-text = "Password cannot be empty."; 60 - } else if password-field.text != confirm-field.text { 64 + } else if !root.verify-mode && password-field.text != confirm-field.text { 61 65 root.error-text = "Passwords do not match."; 62 66 } else { 63 67 root.error-text = "";
+2
ui/settings.slint
··· 55 55 callback theme-mode-changed(int); 56 56 callback text-size-mode-changed(int); 57 57 callback set-password-clicked(); 58 + callback enforced-mode-toggled(bool); 58 59 callback open-config-dir(); 59 60 callback profile-changed(string); 60 61 callback level-changed(int, LevelEntry); ··· 122 123 text-size-mode <=> root.text-size-mode; 123 124 password-is-set <=> root.password-is-set; 124 125 set-password-clicked => { root.set-password-clicked(); } 126 + enforced-mode-toggled(checked) => { root.enforced-mode-toggled(checked); } 125 127 open-config-dir => { root.open-config-dir(); } 126 128 theme-mode-changed(i) => { root.theme-mode-changed(i); } 127 129 text-size-mode-changed(i) => { root.text-size-mode-changed(i); }
+10 -1
ui/views/profile_tab.slint
··· 20 20 callback open-config-dir; 21 21 callback theme-mode-changed(int); 22 22 callback text-size-mode-changed(int); 23 + callback enforced-mode-toggled(bool); 23 24 24 25 vertical-stretch: 1; 25 26 ··· 52 53 Rectangle { horizontal-stretch: 1; } 53 54 54 55 PaperToggle { 55 - checked <=> root.enforced-mode; 56 + checked: root.enforced-mode; 56 57 label: "Enforced mode"; 58 + toggled(checked) => { 59 + if !checked && root.password-is-set { 60 + // Revert — Rust side will verify password first 61 + root.enforced-mode-toggled(false); 62 + } else { 63 + root.enforced-mode = checked; 64 + } 65 + } 57 66 } 58 67 } 59 68