Move duration translations from server defaults to JS SDK
Duration strings are static and not customizable through the console, so they belong in the frontend cookie-banner package instead. Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
@@ -12,9 +12,80 @@
|
|||||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
// PERFORMANCE OF THIS SOFTWARE.
|
// PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
import type { BannerTexts } from "./i18n";
|
|
||||||
import { interpolate } from "./i18n";
|
import { interpolate } from "./i18n";
|
||||||
|
|
||||||
|
interface DurationTexts {
|
||||||
|
[key: string]: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const durationTextsByLanguage: Record<string, DurationTexts> = {
|
||||||
|
en: {
|
||||||
|
duration_year_one: "{{count}} year",
|
||||||
|
duration_year_other: "{{count}} years",
|
||||||
|
duration_month_one: "{{count}} month",
|
||||||
|
duration_month_other: "{{count}} months",
|
||||||
|
duration_week_one: "{{count}} week",
|
||||||
|
duration_week_other: "{{count}} weeks",
|
||||||
|
duration_day_one: "{{count}} day",
|
||||||
|
duration_day_other: "{{count}} days",
|
||||||
|
duration_hour_one: "{{count}} hour",
|
||||||
|
duration_hour_other: "{{count}} hours",
|
||||||
|
duration_minute_one: "{{count}} minute",
|
||||||
|
duration_minute_other: "{{count}} minutes",
|
||||||
|
duration_session: "session",
|
||||||
|
},
|
||||||
|
fr: {
|
||||||
|
duration_year_one: "{{count}} an",
|
||||||
|
duration_year_other: "{{count}} ans",
|
||||||
|
duration_month_one: "{{count}} mois",
|
||||||
|
duration_month_other: "{{count}} mois",
|
||||||
|
duration_week_one: "{{count}} semaine",
|
||||||
|
duration_week_other: "{{count}} semaines",
|
||||||
|
duration_day_one: "{{count}} jour",
|
||||||
|
duration_day_other: "{{count}} jours",
|
||||||
|
duration_hour_one: "{{count}} heure",
|
||||||
|
duration_hour_other: "{{count}} heures",
|
||||||
|
duration_minute_one: "{{count}} minute",
|
||||||
|
duration_minute_other: "{{count}} minutes",
|
||||||
|
duration_session: "session",
|
||||||
|
},
|
||||||
|
de: {
|
||||||
|
duration_year_one: "{{count}} Jahr",
|
||||||
|
duration_year_other: "{{count}} Jahre",
|
||||||
|
duration_month_one: "{{count}} Monat",
|
||||||
|
duration_month_other: "{{count}} Monate",
|
||||||
|
duration_week_one: "{{count}} Woche",
|
||||||
|
duration_week_other: "{{count}} Wochen",
|
||||||
|
duration_day_one: "{{count}} Tag",
|
||||||
|
duration_day_other: "{{count}} Tage",
|
||||||
|
duration_hour_one: "{{count}} Stunde",
|
||||||
|
duration_hour_other: "{{count}} Stunden",
|
||||||
|
duration_minute_one: "{{count}} Minute",
|
||||||
|
duration_minute_other: "{{count}} Minuten",
|
||||||
|
duration_session: "Sitzung",
|
||||||
|
},
|
||||||
|
es: {
|
||||||
|
duration_year_one: "{{count}} año",
|
||||||
|
duration_year_other: "{{count}} años",
|
||||||
|
duration_month_one: "{{count}} mes",
|
||||||
|
duration_month_other: "{{count}} meses",
|
||||||
|
duration_week_one: "{{count}} semana",
|
||||||
|
duration_week_other: "{{count}} semanas",
|
||||||
|
duration_day_one: "{{count}} día",
|
||||||
|
duration_day_other: "{{count}} días",
|
||||||
|
duration_hour_one: "{{count}} hora",
|
||||||
|
duration_hour_other: "{{count}} horas",
|
||||||
|
duration_minute_one: "{{count}} minuto",
|
||||||
|
duration_minute_other: "{{count}} minutos",
|
||||||
|
duration_session: "sesión",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
function getDurationTexts(lang?: string): DurationTexts {
|
||||||
|
if (lang && durationTextsByLanguage[lang]) return durationTextsByLanguage[lang];
|
||||||
|
return durationTextsByLanguage.en;
|
||||||
|
}
|
||||||
|
|
||||||
// [unitSeconds, textKey, snapBuffer]
|
// [unitSeconds, textKey, snapBuffer]
|
||||||
// snapBuffer: if the remainder is within this many seconds of the next
|
// snapBuffer: if the remainder is within this many seconds of the next
|
||||||
// whole unit, round up instead of carrying into smaller units.
|
// whole unit, round up instead of carrying into smaller units.
|
||||||
@@ -27,8 +98,9 @@ const DURATION_UNITS: [number, string, number][] = [
|
|||||||
[60, "duration_minute", 15],
|
[60, "duration_minute", 15],
|
||||||
];
|
];
|
||||||
|
|
||||||
function humanizeDuration(seconds: number, texts?: BannerTexts): string {
|
function humanizeDuration(seconds: number, lang?: string): string {
|
||||||
if (seconds <= 0) return texts?.duration_session ?? "session";
|
const texts = getDurationTexts(lang);
|
||||||
|
if (seconds <= 0) return texts.duration_session;
|
||||||
|
|
||||||
let remaining = seconds;
|
let remaining = seconds;
|
||||||
const parts: string[] = [];
|
const parts: string[] = [];
|
||||||
@@ -48,12 +120,11 @@ function humanizeDuration(seconds: number, texts?: BannerTexts): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const tplKey = count === 1 ? `${key}_one` : `${key}_other`;
|
const tplKey = count === 1 ? `${key}_one` : `${key}_other`;
|
||||||
const tpl = texts?.[tplKey] ?? (count === 1 ? `{{count}} ${key.replace("duration_", "")}` : `{{count}} ${key.replace("duration_", "")}s`);
|
parts.push(interpolate(texts[tplKey], { count: String(count) }));
|
||||||
parts.push(interpolate(tpl, { count: String(count) }));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return parts.length > 0 ? parts.join(", ") : texts?.duration_session ?? "session";
|
return parts.length > 0 ? parts.join(", ") : texts.duration_session;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseCookieName(raw: string): string {
|
export function parseCookieName(raw: string): string {
|
||||||
@@ -62,8 +133,9 @@ export function parseCookieName(raw: string): string {
|
|||||||
return raw.substring(0, eqIdx).trim();
|
return raw.substring(0, eqIdx).trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseDuration(raw: string, texts?: BannerTexts): string {
|
export function parseDuration(raw: string, lang?: string): string {
|
||||||
const session = texts?.duration_session ?? "session";
|
const texts = getDurationTexts(lang);
|
||||||
|
const session = texts.duration_session;
|
||||||
const parts = raw.split(";").map((s) => s.trim());
|
const parts = raw.split(";").map((s) => s.trim());
|
||||||
|
|
||||||
for (const part of parts) {
|
for (const part of parts) {
|
||||||
@@ -71,7 +143,7 @@ export function parseDuration(raw: string, texts?: BannerTexts): string {
|
|||||||
if (lower.startsWith("max-age=")) {
|
if (lower.startsWith("max-age=")) {
|
||||||
const val = parseInt(part.substring(8), 10);
|
const val = parseInt(part.substring(8), 10);
|
||||||
if (isNaN(val) || val <= 0) return session;
|
if (isNaN(val) || val <= 0) return session;
|
||||||
return humanizeDuration(val, texts);
|
return humanizeDuration(val, lang);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,7 +157,7 @@ export function parseDuration(raw: string, texts?: BannerTexts): string {
|
|||||||
(expires.getTime() - Date.now()) / 1000,
|
(expires.getTime() - Date.now()) / 1000,
|
||||||
);
|
);
|
||||||
if (deltaSeconds <= 0) return session;
|
if (deltaSeconds <= 0) return session;
|
||||||
return humanizeDuration(deltaSeconds, texts);
|
return humanizeDuration(deltaSeconds, lang);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,19 +48,6 @@ var defaultUIStringsByLanguage = map[string]map[string]string{
|
|||||||
"privacy_policy_link_text": "Privacy Policy",
|
"privacy_policy_link_text": "Privacy Policy",
|
||||||
"placeholder_text": "This content requires {{category}} cookies.",
|
"placeholder_text": "This content requires {{category}} cookies.",
|
||||||
"placeholder_button": "Manage cookie preferences",
|
"placeholder_button": "Manage cookie preferences",
|
||||||
"duration_year_one": "{{count}} year",
|
|
||||||
"duration_year_other": "{{count}} years",
|
|
||||||
"duration_month_one": "{{count}} month",
|
|
||||||
"duration_month_other": "{{count}} months",
|
|
||||||
"duration_week_one": "{{count}} week",
|
|
||||||
"duration_week_other": "{{count}} weeks",
|
|
||||||
"duration_day_one": "{{count}} day",
|
|
||||||
"duration_day_other": "{{count}} days",
|
|
||||||
"duration_hour_one": "{{count}} hour",
|
|
||||||
"duration_hour_other": "{{count}} hours",
|
|
||||||
"duration_minute_one": "{{count}} minute",
|
|
||||||
"duration_minute_other": "{{count}} minutes",
|
|
||||||
"duration_session": "session",
|
|
||||||
},
|
},
|
||||||
"fr": {
|
"fr": {
|
||||||
"banner_title": "Préférences de cookies",
|
"banner_title": "Préférences de cookies",
|
||||||
@@ -80,19 +67,6 @@ var defaultUIStringsByLanguage = map[string]map[string]string{
|
|||||||
"privacy_policy_link_text": "Politique de confidentialité",
|
"privacy_policy_link_text": "Politique de confidentialité",
|
||||||
"placeholder_text": "Ce contenu nécessite les cookies {{category}}.",
|
"placeholder_text": "Ce contenu nécessite les cookies {{category}}.",
|
||||||
"placeholder_button": "Gérer les préférences de cookies",
|
"placeholder_button": "Gérer les préférences de cookies",
|
||||||
"duration_year_one": "{{count}} an",
|
|
||||||
"duration_year_other": "{{count}} ans",
|
|
||||||
"duration_month_one": "{{count}} mois",
|
|
||||||
"duration_month_other": "{{count}} mois",
|
|
||||||
"duration_week_one": "{{count}} semaine",
|
|
||||||
"duration_week_other": "{{count}} semaines",
|
|
||||||
"duration_day_one": "{{count}} jour",
|
|
||||||
"duration_day_other": "{{count}} jours",
|
|
||||||
"duration_hour_one": "{{count}} heure",
|
|
||||||
"duration_hour_other": "{{count}} heures",
|
|
||||||
"duration_minute_one": "{{count}} minute",
|
|
||||||
"duration_minute_other": "{{count}} minutes",
|
|
||||||
"duration_session": "session",
|
|
||||||
},
|
},
|
||||||
"de": {
|
"de": {
|
||||||
"banner_title": "Cookie-Einstellungen",
|
"banner_title": "Cookie-Einstellungen",
|
||||||
@@ -112,19 +86,6 @@ var defaultUIStringsByLanguage = map[string]map[string]string{
|
|||||||
"privacy_policy_link_text": "Datenschutzrichtlinie",
|
"privacy_policy_link_text": "Datenschutzrichtlinie",
|
||||||
"placeholder_text": "Dieser Inhalt erfordert {{category}}-Cookies.",
|
"placeholder_text": "Dieser Inhalt erfordert {{category}}-Cookies.",
|
||||||
"placeholder_button": "Cookie-Einstellungen verwalten",
|
"placeholder_button": "Cookie-Einstellungen verwalten",
|
||||||
"duration_year_one": "{{count}} Jahr",
|
|
||||||
"duration_year_other": "{{count}} Jahre",
|
|
||||||
"duration_month_one": "{{count}} Monat",
|
|
||||||
"duration_month_other": "{{count}} Monate",
|
|
||||||
"duration_week_one": "{{count}} Woche",
|
|
||||||
"duration_week_other": "{{count}} Wochen",
|
|
||||||
"duration_day_one": "{{count}} Tag",
|
|
||||||
"duration_day_other": "{{count}} Tage",
|
|
||||||
"duration_hour_one": "{{count}} Stunde",
|
|
||||||
"duration_hour_other": "{{count}} Stunden",
|
|
||||||
"duration_minute_one": "{{count}} Minute",
|
|
||||||
"duration_minute_other": "{{count}} Minuten",
|
|
||||||
"duration_session": "Sitzung",
|
|
||||||
},
|
},
|
||||||
"es": {
|
"es": {
|
||||||
"banner_title": "Preferencias de cookies",
|
"banner_title": "Preferencias de cookies",
|
||||||
@@ -144,18 +105,5 @@ var defaultUIStringsByLanguage = map[string]map[string]string{
|
|||||||
"privacy_policy_link_text": "Política de privacidad",
|
"privacy_policy_link_text": "Política de privacidad",
|
||||||
"placeholder_text": "Este contenido requiere cookies de {{category}}.",
|
"placeholder_text": "Este contenido requiere cookies de {{category}}.",
|
||||||
"placeholder_button": "Gestionar preferencias de cookies",
|
"placeholder_button": "Gestionar preferencias de cookies",
|
||||||
"duration_year_one": "{{count}} año",
|
|
||||||
"duration_year_other": "{{count}} años",
|
|
||||||
"duration_month_one": "{{count}} mes",
|
|
||||||
"duration_month_other": "{{count}} meses",
|
|
||||||
"duration_week_one": "{{count}} semana",
|
|
||||||
"duration_week_other": "{{count}} semanas",
|
|
||||||
"duration_day_one": "{{count}} día",
|
|
||||||
"duration_day_other": "{{count}} días",
|
|
||||||
"duration_hour_one": "{{count}} hora",
|
|
||||||
"duration_hour_other": "{{count}} horas",
|
|
||||||
"duration_minute_one": "{{count}} minuto",
|
|
||||||
"duration_minute_other": "{{count}} minutos",
|
|
||||||
"duration_session": "sesión",
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user