Reflect real sync state on the Sync settings page
`SyncConnectionState` was a one-variant enum (`SignedOut`), so the
Sync page rendered "Local-only · sign-in coming soon" even after the
bearer token landed on disk and the upload thread completed. The
state machine now mirrors the actual lifecycle.
What lands:
- `SyncConnectionState` gains `SignedIn`, `AwaitingDeviceApproval`,
`SyncReady { last_synced_at_secs }`, `SyncError { message }`.
`SyncObjectState::Synced` joins the per-object enum so individual
rows can advertise "Synced" once a successful upload lands.
- `BrowserCore` stores the current `SyncConnectionState` and exposes
`set_sync_connection_state`. `sync_status` now propagates the live
state into the snapshot the UI reads.
- `ElyShell::probe_initial_sync_state` inspects
`<profile_data>/sync/bearer.token` synchronously at construction
so the first render of the sync page is honest about whether the
user is signed in.
- A `std::sync::mpsc` channel ferries upload outcomes from the
off-thread worker back to the shell; the existing 8 ms tick
drains it and stamps `core.set_sync_connection_state` with the
freshest result. The UI now shows "Signed in · awaiting first
sync", "Synced · last upload Xm ago", "Sync error · …", and the
worker-special "Signed in · waiting for device approval" when the
server returns `device_not_approved`.
This commit is contained in:
@@ -266,6 +266,7 @@ fn render_state_dot(state: SyncObjectState) -> AnyElement {
|
||||
SyncObjectState::LocalOnly => colors::ink_4(),
|
||||
SyncObjectState::Paused => colors::ink_5(),
|
||||
SyncObjectState::PrivacyControlled => colors::accent(),
|
||||
SyncObjectState::Synced => colors::success(),
|
||||
};
|
||||
|
||||
div().size(px(8.0)).rounded_full().bg(rgb(color)).into_any_element()
|
||||
@@ -304,12 +305,48 @@ fn render_policy_toggle(
|
||||
.into_any_element()
|
||||
}
|
||||
|
||||
fn connection_label(connection: &SyncConnectionState) -> &'static str {
|
||||
fn connection_label(connection: &SyncConnectionState) -> String {
|
||||
match connection {
|
||||
SyncConnectionState::SignedOut => "Local-only · sign-in coming soon",
|
||||
SyncConnectionState::SignedOut => "Local-only · drop a session token to enable".to_string(),
|
||||
SyncConnectionState::SignedIn => "Signed in · awaiting first sync".to_string(),
|
||||
SyncConnectionState::AwaitingDeviceApproval => {
|
||||
"Signed in · waiting for device approval".to_string()
|
||||
}
|
||||
SyncConnectionState::SyncReady { last_synced_at_secs } => {
|
||||
format!("Synced · last upload {}", relative_time_since(*last_synced_at_secs))
|
||||
}
|
||||
SyncConnectionState::SyncError { message } => {
|
||||
format!("Sync error · {}", short_message(message))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn relative_time_since(secs: u64) -> String {
|
||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||
let when = UNIX_EPOCH + Duration::from_secs(secs);
|
||||
let elapsed = SystemTime::now().duration_since(when).unwrap_or_default();
|
||||
let total_secs = elapsed.as_secs();
|
||||
if total_secs < 60 {
|
||||
return format!("{total_secs}s ago");
|
||||
}
|
||||
if total_secs < 3600 {
|
||||
return format!("{}m ago", total_secs / 60);
|
||||
}
|
||||
if total_secs < 86400 {
|
||||
return format!("{}h ago", total_secs / 3600);
|
||||
}
|
||||
format!("{}d ago", total_secs / 86400)
|
||||
}
|
||||
|
||||
fn short_message(message: &str) -> String {
|
||||
const MAX_LEN: usize = 72;
|
||||
if message.len() <= MAX_LEN {
|
||||
return message.to_string();
|
||||
}
|
||||
let truncated: String = message.chars().take(MAX_LEN - 1).collect();
|
||||
format!("{truncated}…")
|
||||
}
|
||||
|
||||
fn sync_object_kind_label(kind: SyncObjectKind) -> &'static str {
|
||||
match kind {
|
||||
SyncObjectKind::Spaces => "Spaces",
|
||||
@@ -329,6 +366,7 @@ fn sync_object_state_label(state: SyncObjectState) -> &'static str {
|
||||
SyncObjectState::LocalOnly => "Local only",
|
||||
SyncObjectState::Paused => "Paused",
|
||||
SyncObjectState::PrivacyControlled => "Privacy controlled",
|
||||
SyncObjectState::Synced => "Synced",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user