Fix: localize reply/forward quote header incl. sender address
The reply/forward quote header was always emitted in English ("On {date},
{from} wrote:", "---------- Forwarded message ----------", From/Date/Subject)
regardless of UI language, in both the main path (lib/quote-header.ts) and the
composer's inline fallback. quote-header.ts now takes an optional localized
QuoteHeaderLabels set (English defaults preserved for back-compat); page.tsx
builds it from a new quote_header message namespace, and the composer fallback
uses the same keys. Added the quote_header namespace to all 17 locales.
Also folds in the forward-sender-address fix: the forward "From:" line now
shows the full "Name <email>" like every mail client (the reply line keeps the
bare name, which reads naturally in "On … wrote:").
This commit is contained in:
@@ -81,6 +81,7 @@ const SCHEDULED_MAILBOX_ID = '__scheduled__';
|
|||||||
export default function Home() {
|
export default function Home() {
|
||||||
const t = useTranslations();
|
const t = useTranslations();
|
||||||
const tCommon = useTranslations('common');
|
const tCommon = useTranslations('common');
|
||||||
|
const tQuote = useTranslations('quote_header');
|
||||||
const { appName } = useConfig();
|
const { appName } = useConfig();
|
||||||
const mailLayout = useSettingsStore((state) => state.mailLayout);
|
const mailLayout = useSettingsStore((state) => state.mailLayout);
|
||||||
const [showComposer, setShowComposer] = useState(false);
|
const [showComposer, setShowComposer] = useState(false);
|
||||||
@@ -1212,13 +1213,20 @@ export default function Home() {
|
|||||||
locale: useLocaleStore.getState().locale,
|
locale: useLocaleStore.getState().locale,
|
||||||
timeFormat: useSettingsStore.getState().timeFormat,
|
timeFormat: useSettingsStore.getState().timeFormat,
|
||||||
unknownLabel: tCommon('unknown'),
|
unknownLabel: tCommon('unknown'),
|
||||||
|
labels: {
|
||||||
|
formatReplyLine: (vars) => tQuote('reply_line', vars),
|
||||||
|
forwardedSeparator: tQuote('forwarded_separator'),
|
||||||
|
fromLabel: tQuote('from_label'),
|
||||||
|
dateLabel: tQuote('date_label'),
|
||||||
|
subjectLabel: tQuote('subject_label'),
|
||||||
|
},
|
||||||
});
|
});
|
||||||
setComposerQuoteHeader(header);
|
setComposerQuoteHeader(header);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn('[quote-header] plugin transform failed; using default', err);
|
console.warn('[quote-header] plugin transform failed; using default', err);
|
||||||
setComposerQuoteHeader(null);
|
setComposerQuoteHeader(null);
|
||||||
}
|
}
|
||||||
}, [tCommon]);
|
}, [tCommon, tQuote]);
|
||||||
|
|
||||||
// Force a clean composer remount on every fresh entry point so prior
|
// Force a clean composer remount on every fresh entry point so prior
|
||||||
// compose state can't bleed into the new session (#329 C). The composer is
|
// compose state can't bleed into the new session (#329 C). The composer is
|
||||||
|
|||||||
@@ -196,6 +196,7 @@ export function EmailComposer({
|
|||||||
}: EmailComposerProps) {
|
}: EmailComposerProps) {
|
||||||
const t = useTranslations('email_composer');
|
const t = useTranslations('email_composer');
|
||||||
const tCommon = useTranslations('common');
|
const tCommon = useTranslations('common');
|
||||||
|
const tQuote = useTranslations('quote_header');
|
||||||
const timeFormat = useSettingsStore((state) => state.timeFormat);
|
const timeFormat = useSettingsStore((state) => state.timeFormat);
|
||||||
const plainTextMode = useSettingsStore((state) => state.plainTextMode);
|
const plainTextMode = useSettingsStore((state) => state.plainTextMode);
|
||||||
const subAddressDelimiter = useSettingsStore((state) => state.subAddressDelimiter);
|
const subAddressDelimiter = useSettingsStore((state) => state.subAddressDelimiter);
|
||||||
@@ -291,6 +292,13 @@ export function EmailComposer({
|
|||||||
const date = replyTo.receivedAt ? formatDateTime(replyTo.receivedAt, timeFormat, { weekday: 'short', year: 'numeric', month: 'short', day: 'numeric' }) : "";
|
const date = replyTo.receivedAt ? formatDateTime(replyTo.receivedAt, timeFormat, { weekday: 'short', year: 'numeric', month: 'short', day: 'numeric' }) : "";
|
||||||
const from = replyTo.from?.[0];
|
const from = replyTo.from?.[0];
|
||||||
const fromStr = from ? `${from.name || from.email}` : tCommon('unknown');
|
const fromStr = from ? `${from.name || from.email}` : tCommon('unknown');
|
||||||
|
// Forward "From:" shows the full sender incl. address; reply line keeps
|
||||||
|
// the bare name (reads naturally in the localized "On … wrote:" line).
|
||||||
|
const fromStrFull = from
|
||||||
|
? (from.name && from.email && from.name !== from.email
|
||||||
|
? `${from.name} <${from.email}>`
|
||||||
|
: (from.email || from.name || tCommon('unknown')))
|
||||||
|
: tCommon('unknown');
|
||||||
|
|
||||||
const originalText = replyTo.body || (replyTo.htmlBody ? htmlToPlainText(replyTo.htmlBody) : '');
|
const originalText = replyTo.body || (replyTo.htmlBody ? htmlToPlainText(replyTo.htmlBody) : '');
|
||||||
const quotedText = originalText.split('\n').map(line => `> ${line}`).join('\n');
|
const quotedText = originalText.split('\n').map(line => `> ${line}`).join('\n');
|
||||||
@@ -311,9 +319,9 @@ export function EmailComposer({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mode === 'forward') {
|
if (mode === 'forward') {
|
||||||
return `${prefix}${signatureBlock}\n\n---------- Forwarded message ----------\nFrom: ${fromStr}\nDate: ${date}\nSubject: ${replyTo.subject || ''}\n\n${originalText}`;
|
return `${prefix}${signatureBlock}\n\n${tQuote('forwarded_separator')}\n${tQuote('from_label')}: ${fromStrFull}\n${tQuote('date_label')}: ${date}\n${tQuote('subject_label')}: ${replyTo.subject || ''}\n\n${originalText}`;
|
||||||
} else if (mode === 'reply' || mode === 'replyAll') {
|
} else if (mode === 'reply' || mode === 'replyAll') {
|
||||||
return `${prefix}${signatureBlock}\n\nOn ${date}, ${fromStr} wrote:\n${quotedText}`;
|
return `${prefix}${signatureBlock}\n\n${tQuote('reply_line', { date, from: fromStr })}\n${quotedText}`;
|
||||||
}
|
}
|
||||||
return prefix;
|
return prefix;
|
||||||
}
|
}
|
||||||
@@ -336,6 +344,11 @@ export function EmailComposer({
|
|||||||
const date = replyTo.receivedAt ? formatDateTime(replyTo.receivedAt, timeFormat, { weekday: 'short', year: 'numeric', month: 'short', day: 'numeric' }) : "";
|
const date = replyTo.receivedAt ? formatDateTime(replyTo.receivedAt, timeFormat, { weekday: 'short', year: 'numeric', month: 'short', day: 'numeric' }) : "";
|
||||||
const from = replyTo.from?.[0];
|
const from = replyTo.from?.[0];
|
||||||
const fromStr = from ? `${from.name || from.email}` : tCommon('unknown');
|
const fromStr = from ? `${from.name || from.email}` : tCommon('unknown');
|
||||||
|
const fromStrFull = from
|
||||||
|
? (from.name && from.email && from.name !== from.email
|
||||||
|
? `${from.name} <${from.email}>`
|
||||||
|
: (from.email || from.name || tCommon('unknown')))
|
||||||
|
: tCommon('unknown');
|
||||||
|
|
||||||
const signatureBlock = buildEmbeddedSignatureHtml(initialSignatureIdentity, {
|
const signatureBlock = buildEmbeddedSignatureHtml(initialSignatureIdentity, {
|
||||||
embed: shouldEmbedSignatureAboveQuote,
|
embed: shouldEmbedSignatureAboveQuote,
|
||||||
@@ -359,8 +372,8 @@ export function EmailComposer({
|
|||||||
// Build quoted content as HTML
|
// Build quoted content as HTML
|
||||||
if (replyTo.htmlBody && (mode === 'reply' || mode === 'replyAll' || mode === 'forward')) {
|
if (replyTo.htmlBody && (mode === 'reply' || mode === 'replyAll' || mode === 'forward')) {
|
||||||
const quoteHeader = mode === 'forward'
|
const quoteHeader = mode === 'forward'
|
||||||
? `---------- Forwarded message ----------<br>From: ${fromStr}<br>Date: ${date}<br>Subject: ${replyTo.subject || ''}<br><br>`
|
? `${tQuote('forwarded_separator')}<br>${tQuote('from_label')}: ${fromStrFull}<br>${tQuote('date_label')}: ${date}<br>${tQuote('subject_label')}: ${replyTo.subject || ''}<br><br>`
|
||||||
: `On ${date}, ${fromStr} wrote:<br>`;
|
: `${tQuote('reply_line', { date, from: fromStr })}<br>`;
|
||||||
// cid: image refs are rewritten so they render in the editor (browsers
|
// cid: image refs are rewritten so they render in the editor (browsers
|
||||||
// can't fetch cid: URLs); see useEffect below for the data-URL backfill.
|
// can't fetch cid: URLs); see useEffect below for the data-URL backfill.
|
||||||
const quotedHtml = rewriteCidImagesForEditor(replyTo.htmlBody);
|
const quotedHtml = rewriteCidImagesForEditor(replyTo.htmlBody);
|
||||||
@@ -370,9 +383,9 @@ export function EmailComposer({
|
|||||||
if (replyTo.body) {
|
if (replyTo.body) {
|
||||||
const escapedOriginal = replyTo.body.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\n/g, '<br>');
|
const escapedOriginal = replyTo.body.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\n/g, '<br>');
|
||||||
if (mode === 'forward') {
|
if (mode === 'forward') {
|
||||||
return `${prefix}${signatureBlock}<br><br>---------- Forwarded message ----------<br>From: ${fromStr}<br>Date: ${date}<br>Subject: ${replyTo.subject || ''}<br><br>${escapedOriginal}`;
|
return `${prefix}${signatureBlock}<br><br>${tQuote('forwarded_separator')}<br>${tQuote('from_label')}: ${fromStrFull}<br>${tQuote('date_label')}: ${date}<br>${tQuote('subject_label')}: ${replyTo.subject || ''}<br><br>${escapedOriginal}`;
|
||||||
} else if (mode === 'reply' || mode === 'replyAll') {
|
} else if (mode === 'reply' || mode === 'replyAll') {
|
||||||
return `${prefix}${signatureBlock}<br><br>On ${date}, ${fromStr} wrote:<br><blockquote style="margin:0 0 0 0.8ex;border-left:2px solid #ccc;padding-left:1ex">${escapedOriginal}</blockquote>`;
|
return `${prefix}${signatureBlock}<br><br>${tQuote('reply_line', { date, from: fromStr })}<br><blockquote style="margin:0 0 0 0.8ex;border-left:2px solid #ccc;padding-left:1ex">${escapedOriginal}</blockquote>`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return prefix;
|
return prefix;
|
||||||
|
|||||||
+38
-4
@@ -10,6 +10,17 @@ import { formatDateTime } from "@/lib/utils";
|
|||||||
import { emailHooks } from "@/lib/plugin-hooks";
|
import { emailHooks } from "@/lib/plugin-hooks";
|
||||||
import type { QuoteHeader, QuoteHeaderContext } from "@/lib/plugin-types";
|
import type { QuoteHeader, QuoteHeaderContext } from "@/lib/plugin-types";
|
||||||
|
|
||||||
|
// Localized label set the caller passes in. Labels live on the client where
|
||||||
|
// useTranslations is available; this module stays framework-agnostic.
|
||||||
|
export interface QuoteHeaderLabels {
|
||||||
|
/** ICU-formatted reply line, e.g. "On {date}, {from} wrote:" with placeholders already substituted. */
|
||||||
|
formatReplyLine: (vars: { date: string; from: string }) => string;
|
||||||
|
forwardedSeparator: string;
|
||||||
|
fromLabel: string;
|
||||||
|
dateLabel: string;
|
||||||
|
subjectLabel: string;
|
||||||
|
}
|
||||||
|
|
||||||
interface BuildArgs {
|
interface BuildArgs {
|
||||||
mode: "reply" | "replyAll" | "forward";
|
mode: "reply" | "replyAll" | "forward";
|
||||||
email: {
|
email: {
|
||||||
@@ -24,10 +35,24 @@ interface BuildArgs {
|
|||||||
locale: string;
|
locale: string;
|
||||||
timeFormat: "12h" | "24h";
|
timeFormat: "12h" | "24h";
|
||||||
unknownLabel: string;
|
unknownLabel: string;
|
||||||
|
/**
|
||||||
|
* Localized labels. Optional for backward compatibility; falls back to
|
||||||
|
* English (matching the original hardcoded behaviour) when not supplied.
|
||||||
|
*/
|
||||||
|
labels?: QuoteHeaderLabels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DEFAULT_LABELS: QuoteHeaderLabels = {
|
||||||
|
formatReplyLine: ({ date, from }) => `On ${date}, ${from} wrote:`,
|
||||||
|
forwardedSeparator: "---------- Forwarded message ----------",
|
||||||
|
fromLabel: "From",
|
||||||
|
dateLabel: "Date",
|
||||||
|
subjectLabel: "Subject",
|
||||||
|
};
|
||||||
|
|
||||||
function defaultHeader(args: BuildArgs): QuoteHeader {
|
function defaultHeader(args: BuildArgs): QuoteHeader {
|
||||||
const { mode, email, timeFormat, unknownLabel } = args;
|
const { mode, email, timeFormat, unknownLabel } = args;
|
||||||
|
const labels = args.labels ?? DEFAULT_LABELS;
|
||||||
const date = email.receivedAt
|
const date = email.receivedAt
|
||||||
? formatDateTime(email.receivedAt, timeFormat, {
|
? formatDateTime(email.receivedAt, timeFormat, {
|
||||||
weekday: "short",
|
weekday: "short",
|
||||||
@@ -38,16 +63,25 @@ function defaultHeader(args: BuildArgs): QuoteHeader {
|
|||||||
: "";
|
: "";
|
||||||
const from = email.from?.[0];
|
const from = email.from?.[0];
|
||||||
const fromStr = from ? `${from.name || from.email}` : unknownLabel;
|
const fromStr = from ? `${from.name || from.email}` : unknownLabel;
|
||||||
|
// Forward header "From:" shows the full sender incl. address ("Name
|
||||||
|
// <email>"), like every mail client. The reply line keeps the bare name
|
||||||
|
// (reads more naturally in "On … wrote:").
|
||||||
|
const fromStrFull = from
|
||||||
|
? (from.name && from.email && from.name !== from.email
|
||||||
|
? `${from.name} <${from.email}>`
|
||||||
|
: (from.email || from.name || unknownLabel))
|
||||||
|
: unknownLabel;
|
||||||
const subject = email.subject || "";
|
const subject = email.subject || "";
|
||||||
|
|
||||||
if (mode === "forward") {
|
if (mode === "forward") {
|
||||||
const text = `---------- Forwarded message ----------\nFrom: ${fromStr}\nDate: ${date}\nSubject: ${subject}\n`;
|
const text = `${labels.forwardedSeparator}\n${labels.fromLabel}: ${fromStrFull}\n${labels.dateLabel}: ${date}\n${labels.subjectLabel}: ${subject}\n`;
|
||||||
const html = `<div>---------- Forwarded message ----------<br>From: ${fromStr}<br>Date: ${date}<br>Subject: ${subject}<br><br></div>`;
|
const html = `<div>${labels.forwardedSeparator}<br>${labels.fromLabel}: ${fromStrFull}<br>${labels.dateLabel}: ${date}<br>${labels.subjectLabel}: ${subject}<br><br></div>`;
|
||||||
return { html, text, wrapInBlockquote: false };
|
return { html, text, wrapInBlockquote: false };
|
||||||
}
|
}
|
||||||
|
|
||||||
const text = `On ${date}, ${fromStr} wrote:\n`;
|
const replyLine = labels.formatReplyLine({ date, from: fromStr });
|
||||||
const html = `<div>On ${date}, ${fromStr} wrote:<br></div>`;
|
const text = `${replyLine}\n`;
|
||||||
|
const html = `<div>${replyLine}<br></div>`;
|
||||||
return { html, text, wrapInBlockquote: true };
|
return { html, text, wrapInBlockquote: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
{
|
{
|
||||||
|
"quote_header": {
|
||||||
|
"reply_line": "Dne {date} napsal(a) {from}:",
|
||||||
|
"forwarded_separator": "---------- Přeposlaná zpráva ----------",
|
||||||
|
"from_label": "Od",
|
||||||
|
"date_label": "Datum",
|
||||||
|
"subject_label": "Předmět"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"title": "Webmail",
|
"title": "Webmail",
|
||||||
"username_label": "E-mail",
|
"username_label": "E-mail",
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
{
|
{
|
||||||
|
"quote_header": {
|
||||||
|
"reply_line": "Den {date} skrev {from}:",
|
||||||
|
"forwarded_separator": "---------- Videresendt besked ----------",
|
||||||
|
"from_label": "Fra",
|
||||||
|
"date_label": "Dato",
|
||||||
|
"subject_label": "Emne"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"title": "Webmail",
|
"title": "Webmail",
|
||||||
"username_label": "Email",
|
"username_label": "Email",
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
{
|
{
|
||||||
|
"quote_header": {
|
||||||
|
"reply_line": "Am {date} schrieb {from}:",
|
||||||
|
"forwarded_separator": "---------- Weitergeleitete Nachricht ----------",
|
||||||
|
"from_label": "Von",
|
||||||
|
"date_label": "Datum",
|
||||||
|
"subject_label": "Betreff"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"title": "Webmail",
|
"title": "Webmail",
|
||||||
"username_label": "E-Mail",
|
"username_label": "E-Mail",
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
{
|
{
|
||||||
|
"quote_header": {
|
||||||
|
"reply_line": "On {date}, {from} wrote:",
|
||||||
|
"forwarded_separator": "---------- Forwarded message ----------",
|
||||||
|
"from_label": "From",
|
||||||
|
"date_label": "Date",
|
||||||
|
"subject_label": "Subject"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"title": "Webmail",
|
"title": "Webmail",
|
||||||
"username_label": "Email",
|
"username_label": "Email",
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
{
|
{
|
||||||
|
"quote_header": {
|
||||||
|
"reply_line": "El {date}, {from} escribió:",
|
||||||
|
"forwarded_separator": "---------- Mensaje reenviado ----------",
|
||||||
|
"from_label": "De",
|
||||||
|
"date_label": "Fecha",
|
||||||
|
"subject_label": "Asunto"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"title": "Correo Web",
|
"title": "Correo Web",
|
||||||
"username_label": "Correo electrónico",
|
"username_label": "Correo electrónico",
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
{
|
{
|
||||||
|
"quote_header": {
|
||||||
|
"reply_line": "Le {date}, {from} a écrit :",
|
||||||
|
"forwarded_separator": "---------- Message transféré ----------",
|
||||||
|
"from_label": "De",
|
||||||
|
"date_label": "Date",
|
||||||
|
"subject_label": "Sujet"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"title": "Webmail",
|
"title": "Webmail",
|
||||||
"username_label": "Email",
|
"username_label": "Email",
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
{
|
{
|
||||||
|
"quote_header": {
|
||||||
|
"reply_line": "Il {date}, {from} ha scritto:",
|
||||||
|
"forwarded_separator": "---------- Messaggio inoltrato ----------",
|
||||||
|
"from_label": "Da",
|
||||||
|
"date_label": "Data",
|
||||||
|
"subject_label": "Oggetto"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"title": "Webmail",
|
"title": "Webmail",
|
||||||
"username_label": "Email",
|
"username_label": "Email",
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
{
|
{
|
||||||
|
"quote_header": {
|
||||||
|
"reply_line": "{date}に{from}が書きました:",
|
||||||
|
"forwarded_separator": "---------- 転送メッセージ ----------",
|
||||||
|
"from_label": "差出人",
|
||||||
|
"date_label": "日付",
|
||||||
|
"subject_label": "件名"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"title": "ウェブメール",
|
"title": "ウェブメール",
|
||||||
"username_label": "メールアドレス",
|
"username_label": "メールアドレス",
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
{
|
{
|
||||||
|
"quote_header": {
|
||||||
|
"reply_line": "{date}에 {from}님이 작성:",
|
||||||
|
"forwarded_separator": "---------- 전달된 메시지 ----------",
|
||||||
|
"from_label": "보낸 사람",
|
||||||
|
"date_label": "날짜",
|
||||||
|
"subject_label": "제목"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"title": "웹메일",
|
"title": "웹메일",
|
||||||
"username_label": "이메일",
|
"username_label": "이메일",
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
{
|
{
|
||||||
|
"quote_header": {
|
||||||
|
"reply_line": "{date} {from} rakstīja:",
|
||||||
|
"forwarded_separator": "---------- Pārsūtītā ziņa ----------",
|
||||||
|
"from_label": "No",
|
||||||
|
"date_label": "Datums",
|
||||||
|
"subject_label": "Tēma"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"title": "Tīmekļa pasts",
|
"title": "Tīmekļa pasts",
|
||||||
"username_label": "E-pasta adrese",
|
"username_label": "E-pasta adrese",
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
{
|
{
|
||||||
|
"quote_header": {
|
||||||
|
"reply_line": "Op {date} schreef {from}:",
|
||||||
|
"forwarded_separator": "---------- Doorgestuurd bericht ----------",
|
||||||
|
"from_label": "Van",
|
||||||
|
"date_label": "Datum",
|
||||||
|
"subject_label": "Onderwerp"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"title": "Webmail",
|
"title": "Webmail",
|
||||||
"username_label": "E-mail",
|
"username_label": "E-mail",
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
{
|
{
|
||||||
|
"quote_header": {
|
||||||
|
"reply_line": "{date}, {from} napisał(a):",
|
||||||
|
"forwarded_separator": "---------- Wiadomość przekazana ----------",
|
||||||
|
"from_label": "Od",
|
||||||
|
"date_label": "Data",
|
||||||
|
"subject_label": "Temat"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"title": "Webmail",
|
"title": "Webmail",
|
||||||
"username_label": "E-mail",
|
"username_label": "E-mail",
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
{
|
{
|
||||||
|
"quote_header": {
|
||||||
|
"reply_line": "Em {date}, {from} escreveu:",
|
||||||
|
"forwarded_separator": "---------- Mensagem encaminhada ----------",
|
||||||
|
"from_label": "De",
|
||||||
|
"date_label": "Data",
|
||||||
|
"subject_label": "Assunto"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"title": "Webmail",
|
"title": "Webmail",
|
||||||
"username_label": "E-mail",
|
"username_label": "E-mail",
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
{
|
{
|
||||||
|
"quote_header": {
|
||||||
|
"reply_line": "{date}, {from} написал:",
|
||||||
|
"forwarded_separator": "---------- Пересланное сообщение ----------",
|
||||||
|
"from_label": "От",
|
||||||
|
"date_label": "Дата",
|
||||||
|
"subject_label": "Тема"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"title": "Веб-почта",
|
"title": "Веб-почта",
|
||||||
"username_label": "Электронная почта",
|
"username_label": "Электронная почта",
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
{
|
{
|
||||||
|
"quote_header": {
|
||||||
|
"reply_line": "{date} tarihinde {from} şunu yazdı:",
|
||||||
|
"forwarded_separator": "---------- İletilen mesaj ----------",
|
||||||
|
"from_label": "Kimden",
|
||||||
|
"date_label": "Tarih",
|
||||||
|
"subject_label": "Konu"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"title": "Webmail",
|
"title": "Webmail",
|
||||||
"username_label": "E-posta",
|
"username_label": "E-posta",
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
{
|
{
|
||||||
|
"quote_header": {
|
||||||
|
"reply_line": "{date}, {from} написав:",
|
||||||
|
"forwarded_separator": "---------- Переслане повідомлення ----------",
|
||||||
|
"from_label": "Від",
|
||||||
|
"date_label": "Дата",
|
||||||
|
"subject_label": "Тема"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"title": "Веб-пошта",
|
"title": "Веб-пошта",
|
||||||
"username_label": "Електронна пошта",
|
"username_label": "Електронна пошта",
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
{
|
{
|
||||||
|
"quote_header": {
|
||||||
|
"reply_line": "在 {date},{from} 写道:",
|
||||||
|
"forwarded_separator": "---------- 转发邮件 ----------",
|
||||||
|
"from_label": "发件人",
|
||||||
|
"date_label": "日期",
|
||||||
|
"subject_label": "主题"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"title": "网页邮箱",
|
"title": "网页邮箱",
|
||||||
"username_label": "邮箱地址",
|
"username_label": "邮箱地址",
|
||||||
|
|||||||
Reference in New Issue
Block a user