fix(gui): say a folder is waiting for its first sync, not up to date

A new sync folder row starts with state idle, so the app called a folder
up to date before any of it reached Drive (B261, issue #53). A mirror
folder that has never synced now reads "waiting for first sync", and
the This computer row counts such folders. All catalogs translated.
This commit is contained in:
nvrl committed 2026-10-31 10:30:52 +01:00
1 parent 9460c93b50
commit 437d14b0f5
12 files changed
+923 -746

No files matched your search

+52 -3
View File
@@ -597,6 +597,19 @@ pub(crate) fn this_computer_subtitle(folders: &[SyncFolderInfo]) -> String {
folders.len() as u64,
&[],
);
// A folder whose first pass has not run is not backed up yet, whatever its
// state column says (`docs/BUGS.md` B261).
let waiting = folders.iter().filter(|f| never_synced(f)).count();
let count = match waiting {
0 => count,
// Translators: {folders} is "N folders backed up"; {n} counts the folders whose first sync has not run yet.
n => ngettext_f(
"{folders} · {n} waiting for its first sync",
"{folders} · {n} waiting for their first sync",
n as u64,
&[("folders", &count)],
),
};
let attention = folders
.iter()
.filter(|f| f.state == "error" || f.state == "conflict")
@@ -613,12 +626,21 @@ pub(crate) fn this_computer_subtitle(folders: &[SyncFolderInfo]) -> String {
}
}
/// Human label for a synced folder's `state` column.
pub(crate) fn sync_state_label(state: &str) -> String {
/// Whether a synced folder is a mirror whose first pass has not finished.
/// Its `state` starts out `idle`, which would read as "up to date".
fn never_synced(folder: &SyncFolderInfo) -> bool {
folder.mode == "mirror" && folder.last_sync == 0 && folder.state == "idle"
}
/// Human label for a synced folder's `state` column. `never_synced` is a
/// mirror folder whose first pass has not finished: its `state` starts out
/// `idle`, and "up to date" would say the opposite of the truth (B261).
pub(crate) fn sync_state_label(state: &str, never_synced: bool) -> String {
match state {
"syncing" => gettext("syncing…"),
"error" => gettext("sync error"),
"conflict" => gettext("needs attention"),
_ if never_synced => gettext("waiting for first sync"),
_ => gettext("up to date"),
}
}
@@ -1274,7 +1296,7 @@ mod tests {
remote_uid: "vol~link".into(),
mode: "mirror".into(),
state: state.into(),
last_sync: 0,
last_sync: 1_700_000_000,
pending_mode: None,
progress: None,
paused: false,
@@ -1286,6 +1308,33 @@ mod tests {
assert_eq!(this_computer_subtitle(&[]), "No folders backed up yet");
}
/// A folder added a moment ago is not backed up yet, and the row must not
/// say it is (`docs/BUGS.md` B261). An on-demand folder has no first sync.
#[test]
fn a_folder_before_its_first_sync_is_not_counted_as_backed_up() {
let new = SyncFolderInfo {
last_sync: 0,
..folder("idle")
};
assert_eq!(
this_computer_subtitle(&[folder("idle"), new.clone()]),
"2 folders backed up · 1 waiting for its first sync"
);
let failed = SyncFolderInfo {
state: "error".into(),
..new.clone()
};
assert_eq!(
this_computer_subtitle(&[new.clone(), failed]),
"2 folders backed up · 1 waiting for its first sync · 1 needs attention"
);
let on_demand = SyncFolderInfo {
mode: "ondemand".into(),
..new
};
assert_eq!(this_computer_subtitle(&[on_demand]), "1 folder backed up");
}
#[test]
fn folders_needing_attention_are_counted_not_hidden() {
// The per-folder rows live on the Sync page, so this row is the only
+22 -1
View File
@@ -1729,7 +1729,10 @@ pub(crate) fn location_subtitle(spec: &MountSpec) -> String {
parts.push(match &spec.progress {
Some(p) => sync_progress_label(p),
None if spec.paused => pgettext("state", "paused"),
None => sync_state_label(&spec.state).to_string(),
None => sync_state_label(
&spec.state,
spec.mode == MountMode::Mirror && spec.last_sync == 0,
),
});
}
// Only the locations that are supposed to have a session report its absence:
@@ -1775,7 +1778,25 @@ mod tests {
MountMode::Mirror,
false,
);
assert_eq!(location_subtitle(&spec), "Synced · waiting for first sync");
}
/// A folder whose first pass has not run is not up to date, though its
/// state column starts out `idle` (`docs/BUGS.md` B261).
#[test]
fn a_folder_reads_up_to_date_only_after_its_first_sync() {
let mut spec = spec(
MountKind::Device { sync_folder_id: 7 },
MountMode::Mirror,
false,
);
assert_eq!(location_subtitle(&spec), "Synced · waiting for first sync");
spec.last_sync = 1_700_000_000;
assert_eq!(location_subtitle(&spec), "Synced · up to date");
// A folder that failed before it ever synced says so.
spec.last_sync = 0;
spec.state = "error".into();
assert_eq!(location_subtitle(&spec), "Synced · sync error");
}
#[test]