Count duplicate originals once the sweep has dated them
A copy becomes a duplicate only once its capture time is read, and on a fresh library that is the sweep, not the scan: the sidebar row stayed hidden until the next launch. The count is refreshed when a sweep that dated anything finishes. Also says on a group left out of the plan that nothing will move, drops an unused method, and names the review's completion callback type for clippy.
This commit is contained in:
@@ -29,6 +29,10 @@ use crate::{AppWindow, DuplicateCopy, DuplicateRow, Duplicates, Library, Page};
|
||||
/// of the library.
|
||||
pub const PAGE: usize = 30;
|
||||
|
||||
/// What runs when a consolidation ends: the grid, the sidebar and the trash
|
||||
/// brought up to date.
|
||||
pub type After = Rc<dyn Fn(&AppWindow)>;
|
||||
|
||||
/// How a group ended in this session.
|
||||
#[derive(Debug, Clone)]
|
||||
enum Ended {
|
||||
@@ -79,9 +83,7 @@ impl DuplicatesController {
|
||||
/// can change the answer.
|
||||
pub fn refresh_count(window: &AppWindow, catalog: &Catalog) {
|
||||
let (groups, _) = dr_catalog::duplicates::count(catalog.connection()).unwrap_or((0, 0));
|
||||
window
|
||||
.global::<Duplicates>()
|
||||
.set_group_count(groups as i32);
|
||||
window.global::<Duplicates>().set_group_count(groups as i32);
|
||||
}
|
||||
|
||||
/// Wire the page. `after` runs when a consolidation ends, to bring the grid,
|
||||
@@ -90,7 +92,7 @@ pub fn wire(
|
||||
window: &AppWindow,
|
||||
ctl: Rc<DuplicatesController>,
|
||||
library: Rc<LibraryController>,
|
||||
after: Rc<dyn Fn(&AppWindow)>,
|
||||
after: After,
|
||||
) {
|
||||
let g = window.global::<Duplicates>();
|
||||
|
||||
@@ -130,8 +132,12 @@ pub fn wire(
|
||||
});
|
||||
}
|
||||
{
|
||||
let (weak, ctl, library, after) =
|
||||
(window.as_weak(), ctl.clone(), library.clone(), after.clone());
|
||||
let (weak, ctl, library, after) = (
|
||||
window.as_weak(),
|
||||
ctl.clone(),
|
||||
library.clone(),
|
||||
after.clone(),
|
||||
);
|
||||
g.on_confirm(move || {
|
||||
let Some(w) = weak.upgrade() else { return };
|
||||
start_consolidate(&w, &ctl, &library, after.clone());
|
||||
@@ -166,7 +172,9 @@ pub fn wire(
|
||||
let index = ctl.page.get() * PAGE + row.max(0) as usize;
|
||||
{
|
||||
let mut review = ctl.review.borrow_mut();
|
||||
let Some(r) = review.get_mut(index) else { return };
|
||||
let Some(r) = review.get_mut(index) else {
|
||||
return;
|
||||
};
|
||||
if (copy as usize) < r.group.copies.len() {
|
||||
r.survivor = copy as usize;
|
||||
}
|
||||
@@ -372,6 +380,10 @@ fn show(window: &AppWindow, ctl: &Rc<DuplicatesController>, library: &Rc<Library
|
||||
(Some(Ended::Failed(s)), _) => (format!("Left as it was: {s}"), true),
|
||||
(None, Check::Unchecked) => ("Not checked yet".to_string(), false),
|
||||
(None, Check::Skip(why)) => (format!("Skipped: {why}"), true),
|
||||
(None, Check::Same(_)) if !r.include => (
|
||||
"The same file · left out: nothing will move".to_string(),
|
||||
false,
|
||||
),
|
||||
(None, Check::Same(edits)) => (
|
||||
if edits.edited.iter().any(|e| *e) {
|
||||
"The same file, with one edit between them".to_string()
|
||||
@@ -533,7 +545,11 @@ pub fn describe(o: &Outcome, carried_edit: Option<&str>) -> String {
|
||||
out
|
||||
}
|
||||
|
||||
fn start_check(window: &AppWindow, ctl: &Rc<DuplicatesController>, library: &Rc<LibraryController>) {
|
||||
fn start_check(
|
||||
window: &AppWindow,
|
||||
ctl: &Rc<DuplicatesController>,
|
||||
library: &Rc<LibraryController>,
|
||||
) {
|
||||
if ctl.running.get() {
|
||||
return;
|
||||
}
|
||||
@@ -566,7 +582,10 @@ fn start_check(window: &AppWindow, ctl: &Rc<DuplicatesController>, library: &Rc<
|
||||
);
|
||||
let job = ctl.activity.begin(
|
||||
crate::activity::Kind::Download,
|
||||
format!("Checking {}", plural(count, "duplicate group", "duplicate groups")),
|
||||
format!(
|
||||
"Checking {}",
|
||||
plural(count, "duplicate group", "duplicate groups")
|
||||
),
|
||||
);
|
||||
ctl.consolidating.set(false);
|
||||
ctl.counts.set((0, 0, 0));
|
||||
@@ -577,7 +596,7 @@ fn start_consolidate(
|
||||
window: &AppWindow,
|
||||
ctl: &Rc<DuplicatesController>,
|
||||
library: &Rc<LibraryController>,
|
||||
after: Rc<dyn Fn(&AppWindow)>,
|
||||
after: After,
|
||||
) {
|
||||
if ctl.running.get() {
|
||||
return;
|
||||
@@ -643,7 +662,7 @@ fn drain(
|
||||
library: &Rc<LibraryController>,
|
||||
rx: Receiver<DupMessage>,
|
||||
job: Activity,
|
||||
after: Option<Rc<dyn Fn(&AppWindow)>>,
|
||||
after: Option<After>,
|
||||
) {
|
||||
ctl.running.set(true);
|
||||
let g = window.global::<Duplicates>();
|
||||
@@ -749,7 +768,7 @@ fn finish(
|
||||
library: &Rc<LibraryController>,
|
||||
job: &Activity,
|
||||
stopped: Option<String>,
|
||||
after: Option<&Rc<dyn Fn(&AppWindow)>>,
|
||||
after: Option<&After>,
|
||||
) {
|
||||
ctl.running.set(false);
|
||||
let g = w.global::<Duplicates>();
|
||||
|
||||
Reference in New Issue
Block a user