refactor: flatten Fluent selectors into one message per variant
This commit is contained in:
parent
06952cd20e
commit
c2525fd0f0
3 changed files with 48 additions and 48 deletions
|
|
@ -33,34 +33,32 @@ mail-message-not-found = Message not found.
|
||||||
|
|
||||||
## Fetch — the status note after a fetch completes
|
## Fetch — the status note after a fetch completes
|
||||||
##
|
##
|
||||||
## `$variant` picks the one combination of "N rejected" and "(cancelled)"
|
## Split from one selector into one message per combination of "N
|
||||||
## that applies, so each case reads as one complete sentence rather than
|
## rejected" and "(cancelled)" that can apply; the caller in ops.rs
|
||||||
## stitched-together fragments.
|
## picks the id to match, since a flat message can't branch on a
|
||||||
|
## variable itself.
|
||||||
|
|
||||||
fetch-result-note = { $variant ->
|
fetch-result-note-rejected = { $total } fetched, { $stored } stored, { $rejected } rejected
|
||||||
[rejected] { $total } fetched, { $stored } stored, { $rejected } rejected
|
fetch-result-note-cancelled = { $total } fetched, { $stored } stored (cancelled)
|
||||||
[cancelled] { $total } fetched, { $stored } stored (cancelled)
|
fetch-result-note-rejected-cancelled = { $total } fetched, { $stored } stored, { $rejected } rejected (cancelled)
|
||||||
[rejected-cancelled] { $total } fetched, { $stored } stored, { $rejected } rejected (cancelled)
|
fetch-result-note-plain = { $total } fetched, { $stored } stored
|
||||||
*[plain] { $total } fetched, { $stored } stored
|
|
||||||
}
|
|
||||||
|
|
||||||
## Send — the status note after a send completes
|
## Send — the status note after a send completes
|
||||||
##
|
##
|
||||||
## `$variant` picks the one combination of trust-change clause and
|
## Split from one selector into one message per combination of
|
||||||
## accept-token clause that applies, each spelled out as a full sentence.
|
## trust-change clause and accept-token clause that can apply; the
|
||||||
## Any warning fumi itself reports is appended separately in code, since
|
## caller in ops.rs picks the id to match. Any warning fumi itself
|
||||||
## that text is fumi's own and not part of this catalogue.
|
## reports is appended separately in code, since that text is fumi's
|
||||||
|
## own and not part of this catalogue.
|
||||||
|
|
||||||
send-result-note = { $variant ->
|
send-result-note-token = Sent to { $address } ({ $bytes } bytes), accept token attached
|
||||||
[token] Sent to { $address } ({ $bytes } bytes), accept token attached
|
send-result-note-unverified = Sent to { $address } ({ $bytes } bytes); new contact learned from an unpinned server (unverified)
|
||||||
[unverified] Sent to { $address } ({ $bytes } bytes); new contact learned from an unpinned server (unverified)
|
send-result-note-unverified-token = Sent to { $address } ({ $bytes } bytes), accept token attached; new contact learned from an unpinned server (unverified)
|
||||||
[unverified-token] Sent to { $address } ({ $bytes } bytes), accept token attached; new contact learned from an unpinned server (unverified)
|
send-result-note-tofu = Sent to { $address } ({ $bytes } bytes); new contact learned (trust on first use)
|
||||||
[tofu] Sent to { $address } ({ $bytes } bytes); new contact learned (trust on first use)
|
send-result-note-tofu-token = Sent to { $address } ({ $bytes } bytes), accept token attached; new contact learned (trust on first use)
|
||||||
[tofu-token] Sent to { $address } ({ $bytes } bytes), accept token attached; new contact learned (trust on first use)
|
send-result-note-rotated = Sent to { $address } ({ $bytes } bytes); contact rotated to a new key (chain verified)
|
||||||
[rotated] Sent to { $address } ({ $bytes } bytes); contact rotated to a new key (chain verified)
|
send-result-note-rotated-token = Sent to { $address } ({ $bytes } bytes), accept token attached; contact rotated to a new key (chain verified)
|
||||||
[rotated-token] Sent to { $address } ({ $bytes } bytes), accept token attached; contact rotated to a new key (chain verified)
|
send-result-note-plain = Sent to { $address } ({ $bytes } bytes)
|
||||||
*[plain] Sent to { $address } ({ $bytes } bytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
## Background-operation status notes
|
## Background-operation status notes
|
||||||
##
|
##
|
||||||
|
|
@ -143,15 +141,13 @@ contacts-import-button = Import
|
||||||
|
|
||||||
## Mail — the open-message meta line
|
## Mail — the open-message meta line
|
||||||
##
|
##
|
||||||
## `$kept` picks the one variant that applies, each a full sentence,
|
## Split from one selector into one message per variant, each a full
|
||||||
## rather than an optional clause spliced onto a shared prefix.
|
## sentence; the caller in view.rs picks `-yes`/`-no` to match `$kept`.
|
||||||
|
|
||||||
mail-meta-to = to
|
mail-meta-to = to
|
||||||
mail-meta-from = from
|
mail-meta-from = from
|
||||||
mail-meta-line = { $kept ->
|
mail-meta-line-no = { $label } { $from } · { $time } UTC · id { $id }…
|
||||||
*[no] { $label } { $from } · { $time } UTC · id { $id }…
|
mail-meta-line-yes = { $label } { $from } · { $time } UTC · id { $id }… · a server copy still exists
|
||||||
[yes] { $label } { $from } · { $time } UTC · id { $id }… · a server copy still exists
|
|
||||||
}
|
|
||||||
mail-no-subject = (no subject)
|
mail-no-subject = (no subject)
|
||||||
mail-no-reply-address = no reply address: can't accept or block
|
mail-no-reply-address = no reply address: can't accept or block
|
||||||
contacts-empty-hint = no contacts
|
contacts-empty-hint = no contacts
|
||||||
|
|
@ -173,8 +169,7 @@ contacts-pin-button-unfetched = Pin server
|
||||||
mail-empty-title = No message selected
|
mail-empty-title = No message selected
|
||||||
mail-empty-description = Pick a message from the list above to read it.
|
mail-empty-description = Pick a message from the list above to read it.
|
||||||
# The two sentences shown under Fetch when the inbox is empty.
|
# The two sentences shown under Fetch when the inbox is empty.
|
||||||
mail-empty-hint = Fetching removes mail from the server once it's stored here.
|
mail-empty-hint = Fetching removes mail from the server once it's stored here. Turn on "Leave mail on server" in Settings to keep it there instead.
|
||||||
Turn on "Leave mail on server" in Settings to keep it there instead.
|
|
||||||
detail-qr-tooltip = Show the address as a QR code
|
detail-qr-tooltip = Show the address as a QR code
|
||||||
detail-copy-tooltip = Copy the address
|
detail-copy-tooltip = Copy the address
|
||||||
|
|
||||||
|
|
@ -194,11 +189,10 @@ contact-state-blocked = blocked
|
||||||
contact-state-verified = verified
|
contact-state-verified = verified
|
||||||
contact-state-tofu = trust on first use
|
contact-state-tofu = trust on first use
|
||||||
# `$state` is one of the four words above, already resolved by the caller
|
# `$state` is one of the four words above, already resolved by the caller
|
||||||
# through `contact_state`; this message only adds the server's pin state.
|
# through `contact_state`. Split from one selector into one message per
|
||||||
contact-meta-line = { $state } · server { $pinned ->
|
# pin state; the caller in view.rs picks `-yes`/`-no` to match `$pinned`.
|
||||||
[yes] pinned
|
contact-meta-line-yes = { $state } · server pinned
|
||||||
*[no] not pinned
|
contact-meta-line-no = { $state } · server not pinned
|
||||||
}
|
|
||||||
|
|
||||||
## Detail pane — the monospace key/value block shared by contacts and the
|
## Detail pane — the monospace key/value block shared by contacts and the
|
||||||
## own identity view. Column widths are padded to these labels in code
|
## own identity view. Column widths are padded to these labels in code
|
||||||
|
|
|
||||||
12
src/ops.rs
12
src/ops.rs
|
|
@ -509,11 +509,13 @@ pub fn fetch(
|
||||||
(false, false) => "plain",
|
(false, false) => "plain",
|
||||||
};
|
};
|
||||||
let mut args = fluent_bundle::FluentArgs::new();
|
let mut args = fluent_bundle::FluentArgs::new();
|
||||||
args.set("variant", variant);
|
|
||||||
args.set("total", fetched.total as i64);
|
args.set("total", fetched.total as i64);
|
||||||
args.set("stored", fetched.stored as i64);
|
args.set("stored", fetched.stored as i64);
|
||||||
args.set("rejected", fetched.rejected.len() as i64);
|
args.set("rejected", fetched.rejected.len() as i64);
|
||||||
Ok(i18n::t_args("fetch-result-note", Some(&args)))
|
Ok(i18n::t_args(
|
||||||
|
&format!("fetch-result-note-{variant}"),
|
||||||
|
Some(&args),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fields fumi itself attaches to every message (sec 5.7, 5.8); a
|
/// Fields fumi itself attaches to every message (sec 5.7, 5.8); a
|
||||||
|
|
@ -634,10 +636,9 @@ pub fn send(
|
||||||
(None, false) => "plain".to_string(),
|
(None, false) => "plain".to_string(),
|
||||||
};
|
};
|
||||||
let mut args = fluent_bundle::FluentArgs::new();
|
let mut args = fluent_bundle::FluentArgs::new();
|
||||||
args.set("variant", variant);
|
|
||||||
args.set("address", addr.short());
|
args.set("address", addr.short());
|
||||||
args.set("bytes", sent.bytes as i64);
|
args.set("bytes", sent.bytes as i64);
|
||||||
let mut note = i18n::t_args("send-result-note", Some(&args));
|
let mut note = i18n::t_args(&format!("send-result-note-{variant}"), Some(&args));
|
||||||
if let Some(warning) = sent.warning {
|
if let Some(warning) = sent.warning {
|
||||||
// Fumi's own warning text, appended as a second, independent
|
// Fumi's own warning text, appended as a second, independent
|
||||||
// clause rather than folded into the catalogue — it isn't ours
|
// clause rather than folded into the catalogue — it isn't ours
|
||||||
|
|
@ -1112,12 +1113,11 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn interpolated_messages_carry_no_bidi_isolation_marks() {
|
fn interpolated_messages_carry_no_bidi_isolation_marks() {
|
||||||
let mut args = fluent_bundle::FluentArgs::new();
|
let mut args = fluent_bundle::FluentArgs::new();
|
||||||
args.set("variant", "plain");
|
|
||||||
args.set("total", 5i64);
|
args.set("total", 5i64);
|
||||||
args.set("stored", 5i64);
|
args.set("stored", 5i64);
|
||||||
args.set("rejected", 0i64);
|
args.set("rejected", 0i64);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
i18n::t_args("fetch-result-note", Some(&args)),
|
i18n::t_args("fetch-result-note-plain", Some(&args)),
|
||||||
"5 fetched, 5 stored"
|
"5 fetched, 5 stored"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
18
src/view.rs
18
src/view.rs
|
|
@ -1810,11 +1810,13 @@ fn render(model: &Carrier, w: &mut CarrierWidgets, sender: &ComponentSender<Carr
|
||||||
// `contact_state` collapses to accepted/blocked once a token
|
// `contact_state` collapses to accepted/blocked once a token
|
||||||
// exists, which says nothing about where the key came from —
|
// exists, which says nothing about where the key came from —
|
||||||
// so the server's pin state is spelled out beside it.
|
// so the server's pin state is spelled out beside it.
|
||||||
let mut meta_args = fluent_bundle::FluentArgs::new();
|
let contact_meta_id = if contact.pinned {
|
||||||
meta_args.set("state", contact_state(contact));
|
"contact-meta-line-yes"
|
||||||
meta_args.set("pinned", if contact.pinned { "yes" } else { "no" });
|
} else {
|
||||||
|
"contact-meta-line-no"
|
||||||
|
};
|
||||||
w.article_meta
|
w.article_meta
|
||||||
.set_text(&i18n::t_args("contact-meta-line", Some(&meta_args)));
|
.set_text(&i18n::t1(contact_meta_id, "state", contact_state(contact)));
|
||||||
let mut body = detail_body(&contact.address, &contact.key, &contact.fingerprint);
|
let mut body = detail_body(&contact.address, &contact.key, &contact.fingerprint);
|
||||||
if !contact.server.is_empty() {
|
if !contact.server.is_empty() {
|
||||||
body.push_str(&format!(
|
body.push_str(&format!(
|
||||||
|
|
@ -1944,13 +1946,17 @@ fn render(model: &Carrier, w: &mut CarrierWidgets, sender: &ComponentSender<Carr
|
||||||
} else {
|
} else {
|
||||||
address
|
address
|
||||||
};
|
};
|
||||||
|
let mail_meta_id = if msg.kept {
|
||||||
|
"mail-meta-line-yes"
|
||||||
|
} else {
|
||||||
|
"mail-meta-line-no"
|
||||||
|
};
|
||||||
let mut meta_args = fluent_bundle::FluentArgs::new();
|
let mut meta_args = fluent_bundle::FluentArgs::new();
|
||||||
meta_args.set("label", label);
|
meta_args.set("label", label);
|
||||||
meta_args.set("from", from);
|
meta_args.set("from", from);
|
||||||
meta_args.set("time", escape(&ops::when(msg.time)));
|
meta_args.set("time", escape(&ops::when(msg.time)));
|
||||||
meta_args.set("id", msg.id[..msg.id.len().min(8)].to_string());
|
meta_args.set("id", msg.id[..msg.id.len().min(8)].to_string());
|
||||||
meta_args.set("kept", if msg.kept { "yes" } else { "no" });
|
let meta = i18n::t_args(mail_meta_id, Some(&meta_args));
|
||||||
let meta = i18n::t_args("mail-meta-line", Some(&meta_args));
|
|
||||||
w.article_meta.set_markup(&meta);
|
w.article_meta.set_markup(&meta);
|
||||||
let headers: Vec<String> = msg
|
let headers: Vec<String> = msg
|
||||||
.headers
|
.headers
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue