From 4ae77badd8c2ae0f46191cf3620cc96fbf026a4c Mon Sep 17 00:00:00 2001
From: Kavin <20838718+FireMasterK@users.noreply.github.com>
Date: Wed, 25 Aug 2021 22:00:21 +0530
Subject: [PATCH] Add i18n translations. (#381)
* Initial prototype.
* Add support for i18n in more places.
---
package.json | 1 +
src/App.vue | 13 ++++++
src/components/LoginPage.vue | 2 +-
src/components/Navigation.vue | 6 +--
src/components/Player.vue | 2 +-
src/components/Preferences.vue | 27 +++++++++--
src/components/TrendingPage.vue | 4 +-
src/components/WatchVideo.vue | 6 +--
src/locales/en.json | 16 +++++++
src/locales/fr.json | 9 ++++
src/main.js | 24 ++++++++--
yarn.lock | 81 +++++++++++++++++++++++++++++++--
12 files changed, 169 insertions(+), 22 deletions(-)
create mode 100644 src/locales/en.json
create mode 100644 src/locales/fr.json
diff --git a/package.json b/package.json
index 92c82d3f..c37f73a8 100644
--- a/package.json
+++ b/package.json
@@ -22,6 +22,7 @@
"shaka-player": "3.2.0",
"uikit": "3.7.2",
"vue": "^3.1.5",
+ "vue-i18n": "^9.1.7",
"vue-router": "^4.0.11",
"xml-js": "^1.6.11"
},
diff --git a/src/App.vue b/src/App.vue
index 66a70eb1..8f026b62 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -58,6 +58,19 @@ export default {
window.db = e.target.result;
};
} else console.log("This browser doesn't support IndexedDB");
+
+ const App = this;
+
+ (async function() {
+ const locale = App.getPreferenceString("hl", "en");
+ if (window.i18n.global.locale.value !== locale) {
+ if (!window.i18n.global.availableLocales.includes(locale)) {
+ const messages = await import("@/locales/" + locale + ".json").then(module => module.default);
+ window.i18n.global.setLocaleMessage(locale, messages);
+ }
+ window.i18n.global.locale.value = locale;
+ }
+ })();
},
};
diff --git a/src/components/LoginPage.vue b/src/components/LoginPage.vue
index 66862fb6..795a63a1 100644
--- a/src/components/LoginPage.vue
+++ b/src/components/LoginPage.vue
@@ -46,7 +46,7 @@ export default {
}
},
activated() {
- document.title = "Login - Piped";
+ document.title = this.$t("titles.login") + " - Piped";
},
methods: {
login() {
diff --git a/src/components/Navigation.vue b/src/components/Navigation.vue
index 7e0a7edb..686f2a28 100644
--- a/src/components/Navigation.vue
+++ b/src/components/Navigation.vue
@@ -32,16 +32,16 @@
Preferences
- Login
+
- Register
+
History
- Feed
+
diff --git a/src/components/Player.vue b/src/components/Player.vue
index e92cec74..40af2be2 100644
--- a/src/components/Player.vue
+++ b/src/components/Player.vue
@@ -307,7 +307,7 @@ export default {
this.player = undefined;
}
if (this.hotkeys) this.hotkeys.unbind();
- this.$refs.container.querySelectorAll("div").forEach(node => node.remove());
+ if (this.$refs.container) this.$refs.container.querySelectorAll("div").forEach(node => node.remove());
},
};
diff --git a/src/components/Preferences.vue b/src/components/Preferences.vue
index c15b1da1..501550c5 100644
--- a/src/components/Preferences.vue
+++ b/src/components/Preferences.vue
@@ -3,7 +3,7 @@
- Preferences
+
@@ -92,6 +92,12 @@
Store Watch History
+
+ Language Selection
+
+
Instances List
@@ -152,10 +158,15 @@ export default {
showComments: true,
minimizeDescription: false,
watchHistory: false,
+ selectedLanguage: "en",
+ languages: [
+ { code: "en", name: "English" },
+ { code: "fr", name: "French" },
+ ],
};
},
activated() {
- document.title = "Preferences - Piped";
+ document.title = this.$t("titles.preferences") + " - Piped";
},
mounted() {
if (Object.keys(this.$route.query).length > 0) this.$router.replace({ query: {} });
@@ -179,6 +190,13 @@ export default {
cdn: split[3].trim(),
});
}
+ if (this.instances.filter(instance => instance.apiurl == this.apiUrl()).length > 0)
+ this.instances.push({
+ name: "Custom Instance",
+ apiurl: this.apiUrl(),
+ locations: "Unknown",
+ cdn: "Unknown",
+ });
});
});
@@ -229,6 +247,7 @@ export default {
this.showComments = this.getPreferenceBoolean("comments", true);
this.minimizeDescription = this.getPreferenceBoolean("minimizeDescription", false);
this.watchHistory = this.getPreferenceBoolean("watchHistory", false);
+ this.selectedLanguage = this.getPreferenceString("hl", "en");
}
},
methods: {
@@ -238,7 +257,8 @@ export default {
if (
this.getPreferenceString("theme", "dark") !== this.selectedTheme ||
- this.getPreferenceBoolean("watchHistory", false) != this.watchHistory
+ this.getPreferenceBoolean("watchHistory", false) != this.watchHistory ||
+ this.getPreferenceString("hl", "en") !== this.selectedLanguage
)
shouldReload = true;
@@ -265,6 +285,7 @@ export default {
localStorage.setItem("comments", this.showComments);
localStorage.setItem("minimizeDescription", this.minimizeDescription);
localStorage.setItem("watchHistory", this.watchHistory);
+ localStorage.setItem("hl", this.selectedLanguage);
if (shouldReload) window.location.reload();
}
diff --git a/src/components/TrendingPage.vue b/src/components/TrendingPage.vue
index 77d16e14..5f0b939e 100644
--- a/src/components/TrendingPage.vue
+++ b/src/components/TrendingPage.vue
@@ -1,5 +1,5 @@
- Trending
+
@@ -33,7 +33,7 @@ export default {
});
},
activated() {
- document.title = "Trending - Piped";
+ document.title = this.$t("titles.trending") + " - Piped";
if (this.videos.length > 0) this.updateWatched(this.videos);
},
methods: {
diff --git a/src/components/WatchVideo.vue b/src/components/WatchVideo.vue
index 0fd059a5..9155c549 100644
--- a/src/components/WatchVideo.vue
+++ b/src/components/WatchVideo.vue
@@ -42,7 +42,7 @@
class="uk-margin-small-left uk-button uk-button-small"
style="background: #222"
>
- Watch on
+ {{ $t("player.watch_on") }}
- Watch on LBRY
+ {{ $t("player.watch_on") }} LBRY
@@ -68,7 +68,7 @@
style="background: #222"
type="button"
>
- {{ subscribed ? "Unsubscribe" : "Subscribe" }}
+ {{ subscribed ? $t("actions.unsubscribe") : $t("actions.subscribe") }}
diff --git a/src/locales/en.json b/src/locales/en.json
new file mode 100644
index 00000000..d4718044
--- /dev/null
+++ b/src/locales/en.json
@@ -0,0 +1,16 @@
+{
+ "titles": {
+ "trending": "Trending",
+ "login": "Login",
+ "register": "Register",
+ "feed": "Feed",
+ "preferences": "Preferences"
+ },
+ "player": {
+ "watch_on": "Watch on"
+ },
+ "actions": {
+ "subscribe": "Subscribe",
+ "unsubscribe": "Unsubscribe"
+ }
+}
diff --git a/src/locales/fr.json b/src/locales/fr.json
new file mode 100644
index 00000000..4d2cd474
--- /dev/null
+++ b/src/locales/fr.json
@@ -0,0 +1,9 @@
+{
+ "titles": {
+ "trending": "Tendances",
+ "login": "Connexion",
+ "register": "S'inscrire",
+ "feed": "Abonnements",
+ "preferences": "Préférences"
+ }
+}
diff --git a/src/main.js b/src/main.js
index 7180c3fe..13775325 100644
--- a/src/main.js
+++ b/src/main.js
@@ -42,6 +42,9 @@ import en from "javascript-time-ago/locale/en";
TimeAgo.addDefaultLocale(en);
+import { createI18n } from "vue-i18n";
+import enLocale from "@/locales/en.json";
+
const timeAgo = new TimeAgo("en-US");
import("./registerServiceWorker");
@@ -104,10 +107,10 @@ const mixin = {
getPreferenceBoolean(key, defaultVal) {
var value;
if (
- (value = this.$route.query[key]) !== undefined ||
+ (value = new URLSearchParams(window.location.search).get(key)) !== null ||
(localStorage && (value = localStorage.getItem(key)) !== null)
) {
- switch (String(value)) {
+ switch (String(value).toLowerCase()) {
case "true":
case "1":
case "on":
@@ -121,7 +124,7 @@ const mixin = {
getPreferenceString(key, defaultVal) {
var value;
if (
- (value = this.$route.query[key]) !== undefined ||
+ (value = new URLSearchParams(window.location.search).get(key)) !== null ||
(localStorage && (value = localStorage.getItem(key)) !== null)
) {
return value;
@@ -130,7 +133,7 @@ const mixin = {
getPreferenceNumber(key, defaultVal) {
var value;
if (
- (value = this.$route.query[key]) !== undefined ||
+ (value = new URLSearchParams(window.location.search).get(key)) !== null ||
(localStorage && (value = localStorage.getItem(key)) !== null)
) {
return Number(value);
@@ -202,7 +205,20 @@ const mixin = {
},
};
+const i18n = createI18n({
+ globalInjection: true,
+ legacy: false,
+ locale: "en",
+ fallbackLocale: "en",
+ messages: {
+ en: enLocale,
+ },
+});
+
+window.i18n = i18n;
+
const app = createApp(App);
+app.use(i18n);
app.use(router);
app.mixin(mixin);
app.component("font-awesome-icon", FontAwesomeIcon);
diff --git a/yarn.lock b/yarn.lock
index 431ba09b..8cb41926 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1011,6 +1011,62 @@
cssnano-preset-default "^4.0.0"
postcss "^7.0.0"
+"@intlify/core-base@9.1.7":
+ version "9.1.7"
+ resolved "https://registry.yarnpkg.com/@intlify/core-base/-/core-base-9.1.7.tgz#a454a492683690bc3d0abab82605ab5a23645bd0"
+ integrity sha512-q1W2j81xbHyfKrNcca/CeJyf0Bcx4u9UDu05l7AaiJbqOseTme2o2I3wp1hDDCtmC7k7HgX0sAygyHNJH9swuQ==
+ dependencies:
+ "@intlify/devtools-if" "9.1.7"
+ "@intlify/message-compiler" "9.1.7"
+ "@intlify/message-resolver" "9.1.7"
+ "@intlify/runtime" "9.1.7"
+ "@intlify/shared" "9.1.7"
+ "@intlify/vue-devtools" "9.1.7"
+
+"@intlify/devtools-if@9.1.7":
+ version "9.1.7"
+ resolved "https://registry.yarnpkg.com/@intlify/devtools-if/-/devtools-if-9.1.7.tgz#a5df0f33e06c3ead3e53b7f4d4b10a2d52309361"
+ integrity sha512-/DcN5FUySSkQhDqx5y1RvxfuCXO3Ot/dUEIOs472qbM7Hyb2qif+eXCnwHBzlI4+wEfQVT6L0PiM1a7Er/ro9g==
+ dependencies:
+ "@intlify/shared" "9.1.7"
+
+"@intlify/message-compiler@9.1.7":
+ version "9.1.7"
+ resolved "https://registry.yarnpkg.com/@intlify/message-compiler/-/message-compiler-9.1.7.tgz#4663fcc2a190f3cc6970e12565c8d6f22beeb719"
+ integrity sha512-JZNkAhr3O7tnbdbRBcpYfqr/Ai26WTzX0K/lV8Y1KVdOIj/dGiamaffdWUdFiDXUnbJRNbPiOaKxy7Pwip3KxQ==
+ dependencies:
+ "@intlify/message-resolver" "9.1.7"
+ "@intlify/shared" "9.1.7"
+ source-map "0.6.1"
+
+"@intlify/message-resolver@9.1.7":
+ version "9.1.7"
+ resolved "https://registry.yarnpkg.com/@intlify/message-resolver/-/message-resolver-9.1.7.tgz#a95d13866c8de85784358039c8845668152e4162"
+ integrity sha512-WTK+OaXJYjyquLGhuCyDvU2WHkG+kXzXeHagmVFHn+s118Jf2143zzkLLUrapP5CtZ/csuyjmYg7b3xQRQAmvw==
+
+"@intlify/runtime@9.1.7":
+ version "9.1.7"
+ resolved "https://registry.yarnpkg.com/@intlify/runtime/-/runtime-9.1.7.tgz#67e0d6b2fd85a5b0b301a151c2f436f93154c3c6"
+ integrity sha512-QURPSlzhOVnRwS2XMGpCDsDkP42kfVBh94aAORxh/gVGzdgJip2vagrIFij/J69aEqdB476WJkMhVjP8VSHmiA==
+ dependencies:
+ "@intlify/message-compiler" "9.1.7"
+ "@intlify/message-resolver" "9.1.7"
+ "@intlify/shared" "9.1.7"
+
+"@intlify/shared@9.1.7":
+ version "9.1.7"
+ resolved "https://registry.yarnpkg.com/@intlify/shared/-/shared-9.1.7.tgz#e7d8bc90cb59dc17dd7b4c85a73db16fcb7891fc"
+ integrity sha512-zt0zlUdalumvT9AjQNxPXA36UgOndUyvBMplh8uRZU0fhWHAwhnJTcf0NaG9Qvr8I1n3HPSs96+kLb/YdwTavQ==
+
+"@intlify/vue-devtools@9.1.7":
+ version "9.1.7"
+ resolved "https://registry.yarnpkg.com/@intlify/vue-devtools/-/vue-devtools-9.1.7.tgz#b08d39bb5f21ba9b1954eab9466e9408129425a7"
+ integrity sha512-DI5Wc0aOiohtBUGUkKAcryCWbbuaO4/PK4Pa/LaNCsFNxbtgR5qkIDmhBv9xVPYGTUhySXxaDDAMvOpBjhPJjw==
+ dependencies:
+ "@intlify/message-resolver" "9.1.7"
+ "@intlify/runtime" "9.1.7"
+ "@intlify/shared" "9.1.7"
+
"@mrmlnc/readdir-enhanced@^2.2.1":
version "2.2.1"
resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde"
@@ -1529,6 +1585,11 @@
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.0.0-beta.15.tgz#ad7cb384e062f165bcf9c83732125bffbc2ad83d"
integrity sha512-quBx4Jjpexo6KDiNUGFr/zF/2A4srKM9S9v2uHgMXSU//hjgq1eGzqkIFql8T9gfX5ZaVOUzYBP3jIdIR3PKIA==
+"@vue/devtools-api@^6.0.0-beta.7":
+ version "6.0.0-beta.15"
+ resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.0.0-beta.15.tgz#ad7cb384e062f165bcf9c83732125bffbc2ad83d"
+ integrity sha512-quBx4Jjpexo6KDiNUGFr/zF/2A4srKM9S9v2uHgMXSU//hjgq1eGzqkIFql8T9gfX5ZaVOUzYBP3jIdIR3PKIA==
+
"@vue/preload-webpack-plugin@^1.1.0":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@vue/preload-webpack-plugin/-/preload-webpack-plugin-1.1.2.tgz#ceb924b4ecb3b9c43871c7a429a02f8423e621ab"
@@ -7844,16 +7905,16 @@ source-map-url@^0.4.0:
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56"
integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==
+source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
+ integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
+
source-map@^0.5.0, source-map@^0.5.6:
version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
-source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
- version "0.6.1"
- resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
- integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
-
source-map@^0.7.3:
version "0.7.3"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
@@ -8689,6 +8750,16 @@ vue-hot-reload-api@^2.3.0:
resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz#532955cc1eb208a3d990b3a9f9a70574657e08f2"
integrity sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==
+vue-i18n@^9.1.7:
+ version "9.1.7"
+ resolved "https://registry.yarnpkg.com/vue-i18n/-/vue-i18n-9.1.7.tgz#6f28dd2135197066508e2e65ab204a019750d773"
+ integrity sha512-ujuuDanoHqtEd4GejWrbG/fXE9nrP51ElsEGxp0WBHfv+/ki0/wyUqkO+4fLikki2obGtXdviTPH0VNpas5K6g==
+ dependencies:
+ "@intlify/core-base" "9.1.7"
+ "@intlify/shared" "9.1.7"
+ "@intlify/vue-devtools" "9.1.7"
+ "@vue/devtools-api" "^6.0.0-beta.7"
+
"vue-loader-v16@npm:vue-loader@^16.1.0":
version "16.5.0"
resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-16.5.0.tgz#09c4e0712466899e34b99a686524f19165fb2892"