mirror of
https://github.com/schlagmichdoch/PairDrop.git
synced 2025-04-23 08:16:19 -04:00
include translations for about buttons and implement translation fallback if used translation is not complete
This commit is contained in:
parent
f50d7438b6
commit
da5038a51a
6 changed files with 78 additions and 52 deletions
|
@ -83,7 +83,7 @@
|
|||
<use xlink:href="#edit-pair-devices-icon" />
|
||||
</svg>
|
||||
</div>
|
||||
<div id="cancel-paste-mode" class="button" data-i18n-key="header.done" data-i18n-attrs="text" hidden>Done</div>
|
||||
<div id="cancel-paste-mode" class="button" data-i18n-key="header.cancel-paste-mode" data-i18n-attrs="text" hidden>Done</div>
|
||||
</header>
|
||||
<!-- Center -->
|
||||
<div id="center">
|
||||
|
@ -161,7 +161,7 @@
|
|||
<x-background class="full center text-center">
|
||||
<x-paper shadow="2">
|
||||
<h2 class="center" data-i18n-key="dialogs.edit-paired-devices-title" data-i18n-attrs="text">Edit Paired Devices</h2>
|
||||
<div class="paired-devices-wrapper" data-i18n-key="dialogs.paired-devices-empty" data-i18n-attrs="data-empty" data-empty="No paired devices."></div>
|
||||
<div class="paired-devices-wrapper" data-i18n-key="dialogs.paired-devices-wrapper" data-i18n-attrs="data-empty" data-empty="No paired devices."></div>
|
||||
<div class="font-subheading center">
|
||||
<p>
|
||||
<span data-i18n-key="dialogs.auto-accept-instructions-1" data-i18n-attrs="text">
|
||||
|
@ -287,7 +287,7 @@
|
|||
<!-- About Page -->
|
||||
<x-about id="about" class="full center column">
|
||||
<header class="row-reverse fade-in">
|
||||
<a href="#" class="close icon-button" data-i18n-key="about.close-about" data-i18n-attrs="text" aria-label="Close About PairDrop">
|
||||
<a href="#" class="close icon-button" data-i18n-key="about.close-about" data-i18n-attrs="aria-label" aria-label="Close About PairDrop">
|
||||
<svg class="icon">
|
||||
<use xlink:href="#close-icon" />
|
||||
</svg>
|
||||
|
@ -303,22 +303,22 @@
|
|||
</div>
|
||||
<div class="font-subheading" data-i18n-key="about.claim" data-i18n-attrs="text">The easiest way to transfer files across devices</div>
|
||||
<div class="row">
|
||||
<a class="icon-button" target="_blank" href="https://github.com/schlagmichdoch/pairdrop" title="PairDrop on Github" rel="noreferrer">
|
||||
<a class="icon-button" target="_blank" href="https://github.com/schlagmichdoch/pairdrop" title="PairDrop on Github" rel="noreferrer" data-i18n-key="about.github" data-i18n-attrs="title">
|
||||
<svg class="icon">
|
||||
<use xlink:href="#github" />
|
||||
</svg>
|
||||
</a>
|
||||
<a class="icon-button" target="_blank" href="https://www.buymeacoffee.com/pairdrop" title="Buy me a coffee!" rel="noreferrer">
|
||||
<a class="icon-button" target="_blank" href="https://www.buymeacoffee.com/pairdrop" title="Buy me a coffee!" rel="noreferrer" data-i18n-key="about.buy-me-a-coffee" data-i18n-attrs="title">
|
||||
<svg class="icon">
|
||||
<use xlink:href="#monetarization" />
|
||||
</svg>
|
||||
</a>
|
||||
<a class="icon-button" target="_blank" href="https://twitter.com/intent/tweet?text=https%3A%2F%2Fpairdrop.net%20by%20https%3A%2F%2Fgithub.com%2Fschlagmichdoch%2F&" title="Tweet about PairDrop" rel="noreferrer">
|
||||
<a class="icon-button" target="_blank" href="https://twitter.com/intent/tweet?text=https%3A%2F%2Fpairdrop.net%20by%20https%3A%2F%2Fgithub.com%2Fschlagmichdoch%2F&" title="Tweet about PairDrop" rel="noreferrer" data-i18n-key="about.tweet" data-i18n-attrs="title">
|
||||
<svg class="icon">
|
||||
<use xlink:href="#twitter" />
|
||||
</svg>
|
||||
</a>
|
||||
<a class="icon-button" target="_blank" href="https://github.com/schlagmichdoch/pairdrop/blob/master/docs/faq.md" title="Frequently asked questions" rel="noreferrer">
|
||||
<a class="icon-button" target="_blank" href="https://github.com/schlagmichdoch/pairdrop/blob/master/docs/faq.md" title="Frequently asked questions" rel="noreferrer" data-i18n-key="about.faq" data-i18n-attrs="title">
|
||||
<svg class="icon">
|
||||
<use xlink:href="#help-outline" />
|
||||
</svg>
|
||||
|
|
|
@ -78,8 +78,12 @@
|
|||
"download-again": "Download again"
|
||||
},
|
||||
"about": {
|
||||
"close-about-aria-label": "Close About PairDrop",
|
||||
"claim": "The easiest way to transfer files across devices"
|
||||
"close-about_aria-label": "Close About PairDrop",
|
||||
"claim": "The easiest way to transfer files across devices",
|
||||
"github_title": "PairDrop on Github",
|
||||
"buy-me-a-coffee_title": "Buy me a coffee!",
|
||||
"tweet_title": "Tweet about PairDrop",
|
||||
"faq_title": "Frequently asked questions"
|
||||
},
|
||||
"notifications": {
|
||||
"display-name-changed-permanently": "Display name is changed permanently.",
|
||||
|
|
|
@ -2,10 +2,10 @@ class Localization {
|
|||
constructor() {
|
||||
Localization.defaultLocale = "en";
|
||||
Localization.supportedLocales = ["en"];
|
||||
|
||||
Localization.translations = {};
|
||||
Localization.defaultTranslations = {};
|
||||
|
||||
const initialLocale = Localization.supportedOrDefault(Localization.browserLocales());
|
||||
const initialLocale = Localization.supportedOrDefault(navigator.languages);
|
||||
|
||||
Localization.setLocale(initialLocale)
|
||||
.then(_ => {
|
||||
|
@ -21,25 +21,21 @@ class Localization {
|
|||
return locales.find(Localization.isSupported) || Localization.defaultLocale;
|
||||
}
|
||||
|
||||
static browserLocales() {
|
||||
return navigator.languages.map(locale =>
|
||||
locale.split("-")[0]
|
||||
);
|
||||
}
|
||||
|
||||
static async setLocale(newLocale) {
|
||||
if (newLocale === Localization.locale) return false;
|
||||
|
||||
const isFirstTranslation = !Localization.locale
|
||||
|
||||
Localization.defaultTranslations = await Localization.fetchTranslationsFor(Localization.defaultLocale);
|
||||
|
||||
const newTranslations = await Localization.fetchTranslationsFor(newLocale);
|
||||
|
||||
if(!newTranslations) return false;
|
||||
|
||||
const firstTranslation = !Localization.locale
|
||||
|
||||
Localization.locale = newLocale;
|
||||
Localization.translations = newTranslations;
|
||||
|
||||
if (firstTranslation) {
|
||||
if (isFirstTranslation) {
|
||||
Events.fire("translation-loaded");
|
||||
}
|
||||
}
|
||||
|
@ -65,30 +61,43 @@ class Localization {
|
|||
for (let i in attrs) {
|
||||
let attr = attrs[i];
|
||||
if (attr === "text") {
|
||||
element.innerText = await Localization.getTranslation(key);
|
||||
element.innerText = Localization.getTranslation(key);
|
||||
} else {
|
||||
element.attr = await Localization.getTranslation(key, attr);
|
||||
element.attr = Localization.getTranslation(key, attr);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static getTranslation(key, attr, data) {
|
||||
static getTranslation(key, attr, data, useDefault=false) {
|
||||
const keys = key.split(".");
|
||||
|
||||
let translationCandidates = Localization.translations;
|
||||
let translationCandidates = useDefault
|
||||
? Localization.defaultTranslations
|
||||
: Localization.translations;
|
||||
|
||||
for (let i=0; i<keys.length-1; i++) {
|
||||
translationCandidates = translationCandidates[keys[i]]
|
||||
}
|
||||
|
||||
let lastKey = keys[keys.length-1];
|
||||
|
||||
if (attr) lastKey += "_" + attr;
|
||||
|
||||
let translation = translationCandidates[lastKey];
|
||||
|
||||
for (key in data) {
|
||||
translation = translation.replace(`{{${key}}}`, data[key]);
|
||||
for (let j in data) {
|
||||
translation = translation.replace(`{{${j}}}`, data[j]);
|
||||
}
|
||||
|
||||
if (!translation) {
|
||||
if (!useDefault) {
|
||||
translation = this.getTranslation(key, attr, data, true);
|
||||
console.warn(`Missing translation entry for your language ${Localization.locale.toUpperCase()}. Using ${Localization.defaultLocale.toUpperCase()} instead.`, key, attr);
|
||||
console.warn("Help translating PairDrop: https://hosted.weblate.org/projects/pairdrop/pairdrop-spa/");
|
||||
} else {
|
||||
console.warn("Missing translation in default language:", key, attr);
|
||||
}
|
||||
}
|
||||
|
||||
return Localization.escapeHTML(translation);
|
||||
|
|
|
@ -83,7 +83,7 @@
|
|||
<use xlink:href="#edit-pair-devices-icon" />
|
||||
</svg>
|
||||
</div>
|
||||
<div id="cancel-paste-mode" class="button" data-i18n-key="header.done" data-i18n-attrs="text" hidden>Done</div>
|
||||
<div id="cancel-paste-mode" class="button" data-i18n-key="header.cancel-paste-mode" data-i18n-attrs="text" hidden>Done</div>
|
||||
</header>
|
||||
<!-- Center -->
|
||||
<div id="center">
|
||||
|
@ -166,7 +166,7 @@
|
|||
<x-background class="full center text-center">
|
||||
<x-paper shadow="2">
|
||||
<h2 class="center" data-i18n-key="dialogs.edit-paired-devices-title" data-i18n-attrs="text">Edit Paired Devices</h2>
|
||||
<div class="paired-devices-wrapper" data-i18n-key="dialogs.paired-devices-empty" data-i18n-attrs="data-empty" data-empty="No paired devices."></div>
|
||||
<div class="paired-devices-wrapper" data-i18n-key="dialogs.paired-devices-wrapper" data-i18n-attrs="data-empty" data-empty="No paired devices."></div>
|
||||
<div class="font-subheading center">
|
||||
<p>
|
||||
<span data-i18n-key="dialogs.auto-accept-instructions-1" data-i18n-attrs="text">
|
||||
|
@ -292,7 +292,7 @@
|
|||
<!-- About Page -->
|
||||
<x-about id="about" class="full center column">
|
||||
<header class="row-reverse fade-in">
|
||||
<a href="#" class="close icon-button" data-i18n-key="about.close-about" data-i18n-attrs="text" aria-label="Close About PairDrop">
|
||||
<a href="#" class="close icon-button" data-i18n-key="about.close-about" data-i18n-attrs="aria-label" aria-label="Close About PairDrop">
|
||||
<svg class="icon">
|
||||
<use xlink:href="#close-icon" />
|
||||
</svg>
|
||||
|
@ -308,22 +308,22 @@
|
|||
</div>
|
||||
<div class="font-subheading" data-i18n-key="about.claim" data-i18n-attrs="text">The easiest way to transfer files across devices</div>
|
||||
<div class="row">
|
||||
<a class="icon-button" target="_blank" href="https://github.com/schlagmichdoch/pairdrop" title="PairDrop on Github" rel="noreferrer">
|
||||
<a class="icon-button" target="_blank" href="https://github.com/schlagmichdoch/pairdrop" title="PairDrop on Github" rel="noreferrer" data-i18n-key="about.github" data-i18n-attrs="title">
|
||||
<svg class="icon">
|
||||
<use xlink:href="#github" />
|
||||
</svg>
|
||||
</a>
|
||||
<a class="icon-button" target="_blank" href="https://www.buymeacoffee.com/pairdrop" title="Buy me a coffee!" rel="noreferrer">
|
||||
<a class="icon-button" target="_blank" href="https://www.buymeacoffee.com/pairdrop" title="Buy me a coffee!" rel="noreferrer" data-i18n-key="about.buy-me-a-coffee" data-i18n-attrs="title">
|
||||
<svg class="icon">
|
||||
<use xlink:href="#monetarization" />
|
||||
</svg>
|
||||
</a>
|
||||
<a class="icon-button" target="_blank" href="https://twitter.com/intent/tweet?text=https%3A%2F%2Fpairdrop.net%20by%20https%3A%2F%2Fgithub.com%2Fschlagmichdoch%2F&" title="Tweet about PairDrop" rel="noreferrer">
|
||||
<a class="icon-button" target="_blank" href="https://twitter.com/intent/tweet?text=https%3A%2F%2Fpairdrop.net%20by%20https%3A%2F%2Fgithub.com%2Fschlagmichdoch%2F&" title="Tweet about PairDrop" rel="noreferrer" data-i18n-key="about.tweet" data-i18n-attrs="title">
|
||||
<svg class="icon">
|
||||
<use xlink:href="#twitter" />
|
||||
</svg>
|
||||
</a>
|
||||
<a class="icon-button" target="_blank" href="https://github.com/schlagmichdoch/pairdrop/blob/master/docs/faq.md" title="Frequently asked questions" rel="noreferrer">
|
||||
<a class="icon-button" target="_blank" href="https://github.com/schlagmichdoch/pairdrop/blob/master/docs/faq.md" title="Frequently asked questions" rel="noreferrer" data-i18n-key="about.faq" data-i18n-attrs="title">
|
||||
<svg class="icon">
|
||||
<use xlink:href="#help-outline" />
|
||||
</svg>
|
||||
|
|
|
@ -78,8 +78,12 @@
|
|||
"download-again": "Download again"
|
||||
},
|
||||
"about": {
|
||||
"close-about-aria-label": "Close About PairDrop",
|
||||
"claim": "The easiest way to transfer files across devices"
|
||||
"close-about_aria-label": "Close About PairDrop",
|
||||
"claim": "The easiest way to transfer files across devices",
|
||||
"github_title": "PairDrop on Github",
|
||||
"buy-me-a-coffee_title": "Buy me a coffee!",
|
||||
"tweet_title": "Tweet about PairDrop",
|
||||
"faq_title": "Frequently asked questions"
|
||||
},
|
||||
"notifications": {
|
||||
"display-name-changed-permanently": "Display name is changed permanently.",
|
||||
|
|
|
@ -2,10 +2,10 @@ class Localization {
|
|||
constructor() {
|
||||
Localization.defaultLocale = "en";
|
||||
Localization.supportedLocales = ["en"];
|
||||
|
||||
Localization.translations = {};
|
||||
Localization.defaultTranslations = {};
|
||||
|
||||
const initialLocale = Localization.supportedOrDefault(Localization.browserLocales());
|
||||
const initialLocale = Localization.supportedOrDefault(navigator.languages);
|
||||
|
||||
Localization.setLocale(initialLocale)
|
||||
.then(_ => {
|
||||
|
@ -21,25 +21,21 @@ class Localization {
|
|||
return locales.find(Localization.isSupported) || Localization.defaultLocale;
|
||||
}
|
||||
|
||||
static browserLocales() {
|
||||
return navigator.languages.map(locale =>
|
||||
locale.split("-")[0]
|
||||
);
|
||||
}
|
||||
|
||||
static async setLocale(newLocale) {
|
||||
if (newLocale === Localization.locale) return false;
|
||||
|
||||
const isFirstTranslation = !Localization.locale
|
||||
|
||||
Localization.defaultTranslations = await Localization.fetchTranslationsFor(Localization.defaultLocale);
|
||||
|
||||
const newTranslations = await Localization.fetchTranslationsFor(newLocale);
|
||||
|
||||
if(!newTranslations) return false;
|
||||
|
||||
const firstTranslation = !Localization.locale
|
||||
|
||||
Localization.locale = newLocale;
|
||||
Localization.translations = newTranslations;
|
||||
|
||||
if (firstTranslation) {
|
||||
if (isFirstTranslation) {
|
||||
Events.fire("translation-loaded");
|
||||
}
|
||||
}
|
||||
|
@ -65,30 +61,43 @@ class Localization {
|
|||
for (let i in attrs) {
|
||||
let attr = attrs[i];
|
||||
if (attr === "text") {
|
||||
element.innerText = await Localization.getTranslation(key);
|
||||
element.innerText = Localization.getTranslation(key);
|
||||
} else {
|
||||
element.attr = await Localization.getTranslation(key, attr);
|
||||
element.attr = Localization.getTranslation(key, attr);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static getTranslation(key, attr, data) {
|
||||
static getTranslation(key, attr, data, useDefault=false) {
|
||||
const keys = key.split(".");
|
||||
|
||||
let translationCandidates = Localization.translations;
|
||||
let translationCandidates = useDefault
|
||||
? Localization.defaultTranslations
|
||||
: Localization.translations;
|
||||
|
||||
for (let i=0; i<keys.length-1; i++) {
|
||||
translationCandidates = translationCandidates[keys[i]]
|
||||
}
|
||||
|
||||
let lastKey = keys[keys.length-1];
|
||||
|
||||
if (attr) lastKey += "_" + attr;
|
||||
|
||||
let translation = translationCandidates[lastKey];
|
||||
|
||||
for (key in data) {
|
||||
translation = translation.replace(`{{${key}}}`, data[key]);
|
||||
for (let j in data) {
|
||||
translation = translation.replace(`{{${j}}}`, data[j]);
|
||||
}
|
||||
|
||||
if (!translation) {
|
||||
if (!useDefault) {
|
||||
translation = this.getTranslation(key, attr, data, true);
|
||||
console.warn(`Missing translation entry for your language ${Localization.locale.toUpperCase()}. Using ${Localization.defaultLocale.toUpperCase()} instead.`, key, attr);
|
||||
console.warn("Help translating PairDrop: https://hosted.weblate.org/projects/pairdrop/pairdrop-spa/");
|
||||
} else {
|
||||
console.warn("Missing translation in default language:", key, attr);
|
||||
}
|
||||
}
|
||||
|
||||
return Localization.escapeHTML(translation);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue