mirror of
https://github.com/narrrl/proton-drive-linux.git
synced 2026-11-04 16:56:59 +01:00
feat(gui): polish pass over wording, icons and responsiveness
The Sync page gives each folder one card with its state, a Synced / Online only switch and a menu for the rest; switching either way asks first and the download prompt shows the free space on the disk. Enabling, disabling and restarting the Proton Drive service ran systemctl on GTK's main thread and froze the window. They now run in the background, and every Retry button goes through one shared restart helper. Ten icons are bundled under resources/icons for glyphs no stock theme has or that read ambiguously (sync, share, people, link, menu, map and so on). A new test fails when the app or search prompt asks for a symbolic icon that is neither bundled nor on a list checked against Adwaita 50, libadwaita and GTK, or when a bundled icon is missing from the resource manifest. The tray's sync icon, which Adwaita 50 no longer ships, is now view-refresh. Wording follows one glossary, recorded in docs/TRANSLATING.md: "Proton Drive service" instead of "mount service" or "daemon", "Online only" instead of "On-demand", "Proton Drive folder" instead of "mountpoint". Dialog headings and buttons use title case and page titles match the sidebar. Dates go through one formatter (app/dates.rs) and sizes through i18n::human_bytes, and the cache label is translated. The status tick stops while the window is hidden or minimized and runs every fifth tick while it is unfocused, refreshing as soon as it gains focus. "Sync complete" is announced only for large batches and only when the window isn't focused. Smaller fixes: Empty Trash hides when there is nothing to empty, copy buttons confirm with a check mark, the sidebar status spins until the first report, and Photos moves Import and Find Duplicates into a menu beside a labelled Select toggle. All catalogs are updated and complete.
This commit is contained in:
1 parent
e872cad058
commit
bd4f797d1f
48 files changed
+12684
-10991
No files matched your search
@@ -49,7 +49,7 @@ pub(crate) struct DetailsWidgets {
|
||||
/// [`DirEntry`] and [`wire_details`] connects the buttons.
|
||||
pub(crate) fn build_details_pane() -> (gtk4::Widget, DetailsWidgets) {
|
||||
let toggle = gtk4::ToggleButton::builder()
|
||||
.icon_name("sidebar-show-right-symbolic")
|
||||
.icon_name("pdfs-details-pane-symbolic")
|
||||
.tooltip_text(gettext("Details (Alt+Enter)"))
|
||||
.build();
|
||||
|
||||
@@ -202,7 +202,7 @@ pub(crate) fn build_details_pane() -> (gtk4::Widget, DetailsWidgets) {
|
||||
let toggle_off = toggle.clone();
|
||||
empty_close.connect_clicked(move |_| toggle_off.set_active(false));
|
||||
let empty_status = adw::StatusPage::builder()
|
||||
.icon_name("sidebar-show-right-symbolic")
|
||||
.icon_name("pdfs-details-pane-symbolic")
|
||||
.title(gettext("No item selected"))
|
||||
.description(gettext("Select a file or folder to see its details."))
|
||||
.vexpand(true)
|
||||
@@ -373,7 +373,7 @@ pub(crate) fn show_details(ui: &Rc<Ui>, entry: &DirEntry) {
|
||||
});
|
||||
d.size_row.set_visible(!entry.is_dir);
|
||||
d.modified_row
|
||||
.set_subtitle(&format_modified(entry.modified));
|
||||
.set_subtitle(&dates::short_date(entry.modified));
|
||||
let rel = entry_rel(ui, entry);
|
||||
let parent = match rel.rfind('/') {
|
||||
Some(i) => &rel[..i],
|
||||
@@ -494,13 +494,13 @@ pub(crate) fn versions_summary(items: &[RevisionInfo]) -> String {
|
||||
match (items.len(), latest) {
|
||||
(0, _) | (_, None) => gettext("No earlier versions"),
|
||||
// Translators: {date} is the date of the only version.
|
||||
(1, Some(t)) => gettext_f("1 version · {date}", &[("date", &format_modified(t))]),
|
||||
(1, Some(t)) => gettext_f("1 version · {date}", &[("date", &dates::short_date(t))]),
|
||||
// Translators: {date} is the date of the newest version.
|
||||
(n, Some(t)) => ngettext_f(
|
||||
"{n} version · latest {date}",
|
||||
"{n} versions · latest {date}",
|
||||
n as u64,
|
||||
&[("date", &format_modified(t))],
|
||||
&[("date", &dates::short_date(t))],
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -427,7 +427,7 @@ pub(crate) fn share_dialog_reload(state: &Rc<ShareDialog>) {
|
||||
_ => toast_error(
|
||||
&state.ui,
|
||||
&gettext("Couldn't load sharing"),
|
||||
&gettext("The mount service didn't respond."),
|
||||
&gettext("The Proton Drive service didn't respond."),
|
||||
),
|
||||
}
|
||||
});
|
||||
@@ -582,6 +582,7 @@ pub(crate) fn repaint_share_link(state: &Rc<ShareDialog>, link: Option<&PublicLi
|
||||
let url_copy = url.clone();
|
||||
copy.connect_clicked(move |btn| {
|
||||
btn.clipboard().set_text(&url_copy);
|
||||
flash_copied(btn, "edit-copy-symbolic");
|
||||
toast(&state_copy.ui, &gettext("Link copied"));
|
||||
});
|
||||
row.add_suffix(©);
|
||||
@@ -718,7 +719,7 @@ pub(crate) fn share_dialog_create_link(
|
||||
_ => toast_error(
|
||||
&state.ui,
|
||||
&gettext("Couldn't create the link"),
|
||||
&gettext("The mount service didn't respond."),
|
||||
&gettext("The Proton Drive service didn't respond."),
|
||||
),
|
||||
}
|
||||
});
|
||||
@@ -756,7 +757,7 @@ pub(crate) fn share_dialog_op(
|
||||
toast_error(
|
||||
&state.ui,
|
||||
&failed,
|
||||
&gettext("The mount service didn't respond."),
|
||||
&gettext("The Proton Drive service didn't respond."),
|
||||
);
|
||||
share_dialog_reload(&state);
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@ pub(crate) fn versions_dialog_reload(state: &Rc<VersionsDialog>) {
|
||||
_ => toast_error(
|
||||
&state.ui,
|
||||
&gettext("Couldn't load versions"),
|
||||
&gettext("The mount service didn't respond."),
|
||||
&gettext("The Proton Drive service didn't respond."),
|
||||
),
|
||||
}
|
||||
});
|
||||
@@ -204,13 +204,13 @@ fn repaint_versions(state: &Rc<VersionsDialog>, items: &[RevisionInfo]) {
|
||||
gettext_f(
|
||||
"{time} · {size}",
|
||||
&[
|
||||
("time", &activity_time(item.created)),
|
||||
("time", &dates::relative(item.created)),
|
||||
("size", &human_bytes(size)),
|
||||
],
|
||||
),
|
||||
)
|
||||
} else {
|
||||
(activity_time(item.created), human_bytes(size))
|
||||
(dates::relative(item.created), human_bytes(size))
|
||||
};
|
||||
if let Some(email) = &item.signed_by {
|
||||
subtitle.push_str(" · ");
|
||||
@@ -266,7 +266,7 @@ fn repaint_versions(state: &Rc<VersionsDialog>, items: &[RevisionInfo]) {
|
||||
/// every device on the account, not only this one.
|
||||
fn prompt_restore_version(state: &Rc<VersionsDialog>, revision_id: &str) {
|
||||
let dialog = adw::AlertDialog::builder()
|
||||
.heading(gettext("Restore version"))
|
||||
.heading(gettext("Restore Version?"))
|
||||
// Translators: {name} is a file name.
|
||||
.body(gettext_f(
|
||||
"Make this version the current content of “{name}”? The version it replaces stays in the history.",
|
||||
@@ -301,7 +301,7 @@ fn prompt_restore_version(state: &Rc<VersionsDialog>, revision_id: &str) {
|
||||
/// Confirm, then permanently delete one revision.
|
||||
fn prompt_delete_version(state: &Rc<VersionsDialog>, revision_id: &str) {
|
||||
let dialog = adw::AlertDialog::builder()
|
||||
.heading(gettext("Delete version"))
|
||||
.heading(gettext("Delete Version?"))
|
||||
.body(gettext(
|
||||
"Delete this version permanently? Its content can't be recovered.",
|
||||
))
|
||||
@@ -377,7 +377,7 @@ fn versions_dialog_op(state: &Rc<VersionsDialog>, request: Request, done: &str,
|
||||
_ => toast_error(
|
||||
&state.ui,
|
||||
&failed,
|
||||
&gettext("The mount service didn't respond."),
|
||||
&gettext("The Proton Drive service didn't respond."),
|
||||
),
|
||||
}
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user