| author | |
| committer | |
| log | ec793693c96b0c8395e2a0d8f93bc6fd6af9b469 |
| tree | 9bfb50f054f8660c2537582e1baad5e98a4bf7c2 |
| parent | 2b462d10dda0898b5f553701b46982d68bfc8661 |
| signature | Signed by SSH key SHA256:52mNGHRsVFBDED9IAX5pe+LRWUefqTbxEReunq21QvU |
Lock All Sections stood enabled with no protected section unlocked; the File
menu's and palette's Close This Notebook on an iCloud notebook, which its
context menu already disables, since the app's iCloud folder lists every
notebook in it; and Notebook Recycle Bin on a notebook whose bin holds no
sections, where it ended in an alert.
Assisted-by: claude-opus-5.54 files changed, 28 insertions(+), 4 deletions(-)
crates/snowbound/src/commands.rs+11-3| ... | ... | @@ -1152,7 +1152,13 @@ impl State { |
| 1152 | 1152 | | Id::CustomizeTags |
| 1153 | 1153 | | Id::Help |
| 1154 | 1154 | | Id::CheckForUpdates => enabled(!modal), |
| 1155 | Id::CloseNotebook => enabled(!modal && self.notebook().is_some()), | |
| 1155 | // The app's iCloud Drive folder lists every notebook in it. | |
| 1156 | Id::CloseNotebook => enabled( | |
| 1157 | !modal | |
| 1158 | && self | |
| 1159 | .notebook() | |
| 1160 | .is_some_and(|library| !crate::manage::in_icloud_folder(&library.location)), | |
| 1161 | ), | |
| 1156 | 1162 | Id::OpenShared => enabled(!modal && cfg!(feature = "live")), |
| 1157 | 1163 | #[cfg(feature = "live")] |
| 1158 | 1164 | Id::LiveShare => enabled( |
| ... | ... | @@ -1169,7 +1175,7 @@ impl State { |
| 1169 | 1175 | enabled: !modal |
| 1170 | 1176 | && self |
| 1171 | 1177 | .notebook() |
| 1172 | .is_some_and(|library| library.catalog().is_some()), | |
| 1178 | .is_some_and(|library| self.recycle_bin_available(library)), | |
| 1173 | 1179 | checked: Some(self.in_recycle_bin()), |
| 1174 | 1180 | }, |
| 1175 | 1181 | Id::EmptyRecycleBin => enabled( |
| ... | ... | @@ -1195,7 +1201,9 @@ impl State { |
| 1195 | 1201 | .is_some_and(|library| self.reads.shown(&library.location)), |
| 1196 | 1202 | ), |
| 1197 | 1203 | }, |
| 1198 | Id::LockAll => enabled(!modal), | |
| 1204 | Id::LockAll => { | |
| 1205 | enabled(!modal && self.notebooks.iter().any(|library| library.any_unlocked())) | |
| 1206 | } | |
| 1199 | 1207 | Id::ShowNotebook => enabled( |
| 1200 | 1208 | !modal |
| 1201 | 1209 | && self |
crates/snowbound/src/library.rs+5| ... | ... | @@ -1105,6 +1105,11 @@ impl Library { |
| 1105 | 1105 | keys.get(&identity).map(|(key, _)| key.clone()) |
| 1106 | 1106 | } |
| 1107 | 1107 | |
| 1108 | /// Whether any of its password-protected sections is unlocked, which Lock All would lock. | |
| 1109 | pub fn any_unlocked(&self) -> bool { | |
| 1110 | self.keys.0.lock().is_ok_and(|keys| !keys.is_empty()) | |
| 1111 | } | |
| 1112 | ||
| 1108 | 1113 | /// Marks the unlocked section at catalog `path` worked in now. |
| 1109 | 1114 | pub fn touch(&self, path: &str) { |
| 1110 | 1115 | if let (Some(identity), Ok(mut keys)) = (self.section_identity(path), self.keys.0.lock()) |
crates/snowbound/src/menus.rs+1-1| ... | ... | @@ -587,7 +587,7 @@ impl State { |
| 587 | 587 | item( |
| 588 | 588 | Action::RecycleBin, |
| 589 | 589 | "Notebook Recycle Bin", |
| 590 | library.catalog().is_none(), | |
| 590 | !self.recycle_bin_available(library), | |
| 591 | 591 | false, |
| 592 | 592 | ), |
| 593 | 593 | item( |
crates/snowbound/src/recycle.rs+11| ... | ... | @@ -38,6 +38,17 @@ impl State { |
| 38 | 38 | (self.session.as_ref()).is_some_and(|session| binned(&session.tabs[session.tab].path)) |
| 39 | 39 | } |
| 40 | 40 | |
| 41 | /// Whether Notebook Recycle Bin can do anything on `library`: leave its bin, shown, or | |
| 42 | /// show one holding sections. | |
| 43 | pub(crate) fn recycle_bin_available(&self, library: &Arc<Library>) -> bool { | |
| 44 | let shown = self | |
| 45 | .session | |
| 46 | .as_ref() | |
| 47 | .is_some_and(|session| Arc::ptr_eq(&session.library, library)); | |
| 48 | library.catalog().is_some() | |
| 49 | && (shown && self.in_recycle_bin() || !library.tabs(BIN).is_empty()) | |
| 50 | } | |
| 51 | ||
| 41 | 52 | /// Notebook Recycle Bin: shows `library`'s bin at its first section holding pages, or |
| 42 | 53 | /// while it shows, goes back to the notebook. |
| 43 | 54 | pub(crate) fn toggle_recycle_bin(&mut self, library: Arc<Library>) { |