From c7f85e6283f359f4bc24dada08e116d0ac0615f3 Mon Sep 17 00:00:00 2001 From: Nihal Gonsalves Date: Mon, 10 Jul 2023 20:10:45 +0200 Subject: [PATCH] fix(web-push): re-init i18n on each sw message --- web/public/sw.js | 19 ++++++++++++------- web/src/app/i18n.js | 33 +++++++++++++++++---------------- web/src/components/App.jsx | 4 +++- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/web/public/sw.js b/web/public/sw.js index 33154628..56d66f16 100644 --- a/web/public/sw.js +++ b/web/public/sw.js @@ -7,8 +7,7 @@ import { clientsClaim } from "workbox-core"; import { dbAsync } from "../src/app/db"; import { toNotificationParams, icon, badge } from "../src/app/notificationUtils"; - -import i18n from "../src/app/i18n"; +import initI18n from "../src/app/i18n"; /** * General docs for service workers and PWAs: @@ -67,8 +66,10 @@ const handlePushMessage = async (data) => { * Handle a received web push subscription expiring. */ const handlePushSubscriptionExpiring = async (data) => { - await self.registration.showNotification(i18n.t("web_push_subscription_expiring_title"), { - body: i18n.t("web_push_subscription_expiring_body"), + const t = await initI18n(); + + await self.registration.showNotification(t("web_push_subscription_expiring_title"), { + body: t("web_push_subscription_expiring_body"), icon, data, badge, @@ -80,8 +81,10 @@ const handlePushSubscriptionExpiring = async (data) => { * permission can be revoked by the browser. */ const handlePushUnknown = async (data) => { - await self.registration.showNotification(i18n.t("web_push_unknown_notification_title"), { - body: i18n.t("web_push_unknown_notification_body"), + const t = await initI18n(); + + await self.registration.showNotification(t("web_push_unknown_notification_title"), { + body: t("web_push_unknown_notification_body"), icon, data, badge, @@ -107,6 +110,8 @@ const handlePush = async (data) => { * This is also called when the user clicks on an action button. */ const handleClick = async (event) => { + const t = await initI18n(); + const clients = await self.clients.matchAll({ type: "window" }); const rootUrl = new URL(self.location.origin); @@ -147,7 +152,7 @@ const handleClick = async (event) => { } } catch (e) { console.error("[ServiceWorker] Error performing http action", e); - self.registration.showNotification(`${i18n.t("notifications_actions_failed_notification")}: ${action.label} (${action.action})`, { + self.registration.showNotification(`${t("notifications_actions_failed_notification")}: ${action.label} (${action.action})`, { body: e.message, icon, badge, diff --git a/web/src/app/i18n.js b/web/src/app/i18n.js index 2bc315c0..298f595c 100644 --- a/web/src/app/i18n.js +++ b/web/src/app/i18n.js @@ -1,4 +1,4 @@ -import i18n from "i18next"; +import i18next from "i18next"; import Backend from "i18next-http-backend"; import LanguageDetector from "i18next-browser-languagedetector"; import { initReactI18next } from "react-i18next"; @@ -11,19 +11,20 @@ import { initReactI18next } from "react-i18next"; // See example project here: // https://github.com/i18next/react-i18next/tree/master/example/react -i18n - .use(Backend) - .use(LanguageDetector) - .use(initReactI18next) - .init({ - fallbackLng: "en", - debug: true, - interpolation: { - escapeValue: false, // not needed for react as it escapes by default - }, - backend: { - loadPath: "/static/langs/{{lng}}.json", - }, - }); +const initI18n = () => + i18next + .use(Backend) + .use(LanguageDetector) + .use(initReactI18next) + .init({ + fallbackLng: "en", + debug: true, + interpolation: { + escapeValue: false, // not needed for react as it escapes by default + }, + backend: { + loadPath: "/static/langs/{{lng}}.json", + }, + }); -export default i18n; +export default initI18n; diff --git a/web/src/components/App.jsx b/web/src/components/App.jsx index 8b60b3e8..d22ec66f 100644 --- a/web/src/components/App.jsx +++ b/web/src/components/App.jsx @@ -20,10 +20,12 @@ import Messaging from "./Messaging"; import Login from "./Login"; import Signup from "./Signup"; import Account from "./Account"; -import "../app/i18n"; // Translations! +import initI18n from "../app/i18n"; // Translations! import prefs, { THEME } from "../app/Prefs"; import RTLCacheProvider from "./RTLCacheProvider"; +initI18n(); + export const AccountContext = createContext(null); const darkModeEnabled = (prefersDarkMode, themePreference) => {