Translate English built from template literals in attributes
i18n-literals now flags a template literal in a UI attribute or prop when
there are words between its values: `Remove ${email}`, `${name} — shared by
${owner}`. It cannot be a catalogue key as written, so neither the key
exemption nor the sentence-shape test applies. A template that is only
punctuation around values, like `${name} (${size})`, is left alone.
The twelve it found are now keys with placeholders: the quota bar title,
the address menu's label, a folder's subfolder unread count, a recipient
chip's remove button, the contact editor's title, shared and available
calendars and address books, the date and time fields' labels, the
attachment title's fallback name, and the free/busy bar. The bar showed
the raw JMAP busyStatus ("confirmed") and now says Busy, Tentative or
Unavailable.
11 new keys in all nine catalogues. Remove {address}, Date, Time, Busy and
Tentative already existed.
This commit is contained in:
@@ -156,7 +156,7 @@ export function ContactEditor({ card, defaultBookId, onClose, onSaved }: Props)
|
||||
const photoSrc = photo?.dataUrl ?? (!removePhoto && existingPhoto ? (existingPhoto.uri?.startsWith("data:") ? existingPhoto.uri : existingPhoto.blobId ? client.downloadUrl(contacts.accountId!, existingPhoto.blobId, "photo", existingPhoto.mediaType ?? "image/jpeg", true) : null) : null);
|
||||
|
||||
return (
|
||||
<Dialog open onClose={onClose} title={isNew ? t("New contact") : `Edit ${contactDisplayName(card as ContactCard)}`} size="lg" footer={<><button className="btn" onClick={onClose}>{t("Cancel")}</button><button className="btn btn-primary" disabled={busy} onClick={() => void save()}>{busy ? t("Saving…") : t("Save")}</button></>}>
|
||||
<Dialog open onClose={onClose} title={isNew ? t("New contact") : t("Edit {name}", { name: contactDisplayName(card as ContactCard) })} size="lg" footer={<><button className="btn" onClick={onClose}>{t("Cancel")}</button><button className="btn btn-primary" disabled={busy} onClick={() => void save()}>{busy ? t("Saving…") : t("Save")}</button></>}>
|
||||
<div className="contact-form">
|
||||
<div className="row" style={{ gap: 16, marginBottom: 12 }}>
|
||||
<label className="avatar xl" style={{ background: "var(--bg-sunken)", color: "var(--fg-muted)", cursor: "pointer", position: "relative" }} title={t("Change photo")}>
|
||||
|
||||
@@ -157,7 +157,7 @@ export function ContactsSidebar() {
|
||||
key={`${accountId}:${book.id}`}
|
||||
className={`nav-item ${isOn(accountId, book.id) ? "active" : ""}`}
|
||||
onClick={() => contacts.select({ accountId, bookId: book.id })}
|
||||
title={`${book.name} — shared by ${accountName}`}
|
||||
title={t("{name} — shared by {owner}", { name: book.name, owner: accountName })}
|
||||
onContextMenu={(e) => openMenuAt(e, { kind: "shared", accountId, book })}
|
||||
>
|
||||
<BookOpen size={17} />
|
||||
@@ -181,7 +181,7 @@ export function ContactsSidebar() {
|
||||
<>
|
||||
<div className="nav-section"><span>{t("Available to add")}</span></div>
|
||||
{available.map(({ accountId, accountName, book }) => (
|
||||
<div key={`${accountId}:${book.id}`} className="nav-item" title={`${book.name} — from ${accountName}`}>
|
||||
<div key={`${accountId}:${book.id}`} className="nav-item" title={t("{name} — from {owner}", { name: book.name, owner: accountName })}>
|
||||
<BookOpen size={17} className="faint" />
|
||||
<span className="grow truncate faint">{book.name}</span>
|
||||
<button
|
||||
|
||||
Reference in New Issue
Block a user