From e233cd554c4a40977130c11d9045b8e7ca2269bd Mon Sep 17 00:00:00 2001
From: Christoph Reiter <reiter.christoph@gmail.com>
Date: Thu, 1 Jul 2021 16:51:21 +0200
Subject: [PATCH] file-hanlding: one i18next instance per element

---
 packages/file-handling/src/clipboard.js       | 19 ++++++++++++---
 packages/file-handling/src/demo.js            |  9 ++++---
 packages/file-handling/src/file-sink.js       | 11 +++++----
 packages/file-handling/src/file-source.js     |  9 ++++---
 packages/file-handling/src/i18n.js            |  6 +++--
 .../src/nextcloud-file-picker.js              | 24 +++++++++++++++----
 6 files changed, 59 insertions(+), 19 deletions(-)

diff --git a/packages/file-handling/src/clipboard.js b/packages/file-handling/src/clipboard.js
index 57c45cac..1cc9a43c 100644
--- a/packages/file-handling/src/clipboard.js
+++ b/packages/file-handling/src/clipboard.js
@@ -1,4 +1,4 @@
-import {i18n} from './i18n';
+import {createInstance} from './i18n';
 import {css, html} from 'lit-element';
 import {ScopedElementsMixin} from '@open-wc/scoped-elements';
 import * as commonUtils from '@dbp-toolkit/common/utils';
@@ -20,7 +20,8 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
 
     constructor() {
         super();
-        this.lang = 'de';
+        this._i18n = createInstance();
+        this.lang = this._i18n.language;
         this.allowedMimeTypes = '*/*';
         this.clipboardFiles = {files: ''};
         this.clipboardSelectBtnDisabled = true;
@@ -82,7 +83,7 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
         changedProperties.forEach((oldValue, propName) => {
             switch (propName) {
                 case "lang":
-                    i18n.changeLanguage(this.lang);
+                    this._i18n.changeLanguage(this.lang);
                     break;
                 case "clipboardFiles":
                     this.generateClipboardTable();
@@ -105,6 +106,7 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
 
 
     connectedCallback() {
+        const i18n = this._i18n;
         super.connectedCallback();
         const that = this;
         this.updateComplete.then(() => {
@@ -337,6 +339,7 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
      * @param files
      */
     async sendClipboardFiles(files) {
+        const i18n = this._i18n;
         for (let i = 0; i < files.length; i ++) {
             await this.sendFileEvent(files[i].file);
         }
@@ -363,6 +366,7 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
      * @param event
      */
     onReceiveBeforeUnload(event) {
+        const i18n = this._i18n;
 
         // we don't need to stop if there are no signed files
         if (this.clipboardFiles.files.length === 0) {
@@ -425,6 +429,8 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
      */
     saveFilesToClipboard()
     {
+        const i18n = this._i18n;
+
         //save it
         let data = {};
         let files = [];
@@ -455,6 +461,8 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
      * @param event
      */
     finishedSaveFilesToClipboard(event) {
+        const i18n = this._i18n;
+
         send({
             "summary": i18n.t('clipboard.saved-files-title', {count: event.detail.count}),
             "body": i18n.t('clipboard.saved-files-body', {count: event.detail.count}),
@@ -491,6 +499,8 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
      *
      */
     clearClipboard() {
+        const i18n = this._i18n;
+
         if (this.tabulatorTable && this.tabulatorTable.getSelectedData().length > 0) {
             let count = this.tabulatorTable.getSelectedData().length;
             this.tabulatorTable.deleteRow(this.tabulatorTable.getSelectedRows());
@@ -526,6 +536,7 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
      * @returns {html}
      */
     getAdditionalButtons() {
+        const i18n = this._i18n;
         let buttonsAreDisabled = this.clipboardFiles.files.length === 0 ? true : this.clipboardSelectBtnDisabled;
         return html`
             <div class="flex-container additional-button-container">
@@ -590,6 +601,7 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
      * @returns {html}
      */
     getClipboardSink() {
+        const i18n = this._i18n;
         const tabulatorCss = commonUtils.getAssetURL(pkgName, 'tabulator-tables/css/tabulator.min.css');
         return html`
             <div class="wrapper">
@@ -624,6 +636,7 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) {
      */
     getClipboardSource() {
         const tabulatorCss = commonUtils.getAssetURL(pkgName, 'tabulator-tables/css/tabulator.min.css');
+        const i18n = this._i18n;
         return html`
             <div class="wrapper">
                 <div class="content">
diff --git a/packages/file-handling/src/demo.js b/packages/file-handling/src/demo.js
index ede45f52..e723a9a9 100644
--- a/packages/file-handling/src/demo.js
+++ b/packages/file-handling/src/demo.js
@@ -1,4 +1,4 @@
-import {i18n} from './i18n';
+import {createInstance} from './i18n';
 import {html, LitElement} from 'lit-element';
 import {unsafeHTML} from 'lit-html/directives/unsafe-html.js';
 import {ScopedElementsMixin} from '@open-wc/scoped-elements';
@@ -9,7 +9,8 @@ import * as commonUtils from '@dbp-toolkit/common/utils';
 export class FileSourceDemo extends ScopedElementsMixin(LitElement) {
     constructor() {
         super();
-        this.lang = 'de';
+        this._i18n = createInstance();
+        this.lang = this._i18n.language;
         this.url = '';
         this.selectedFiles = [];
         this.selectedFilesCount = 0;
@@ -46,7 +47,7 @@ export class FileSourceDemo extends ScopedElementsMixin(LitElement) {
     update(changedProperties) {
         changedProperties.forEach((oldValue, propName) => {
             if (propName === "lang") {
-                i18n.changeLanguage(this.lang);
+                this._i18n.changeLanguage(this.lang);
             }
         });
 
@@ -77,6 +78,8 @@ export class FileSourceDemo extends ScopedElementsMixin(LitElement) {
     }
 
     render() {
+        const i18n = this._i18n;
+
         return html`
             <style>
                 dbp-file-source.clean {
diff --git a/packages/file-handling/src/file-sink.js b/packages/file-handling/src/file-sink.js
index 16b86316..8c3b2afa 100644
--- a/packages/file-handling/src/file-sink.js
+++ b/packages/file-handling/src/file-sink.js
@@ -1,4 +1,4 @@
-import {i18n} from './i18n';
+import {createInstance} from './i18n';
 import {css, html} from 'lit-element';
 import {ScopedElementsMixin} from '@open-wc/scoped-elements';
 import DBPLitElement from '@dbp-toolkit/common/dbp-lit-element';
@@ -21,7 +21,8 @@ export class FileSink extends ScopedElementsMixin(DBPLitElement) {
     constructor() {
         super();
         this.context = '';
-        this.lang = 'de';
+        this._i18n = createInstance();
+        this.lang = this._i18n.language;
         this.nextcloudAuthUrl = '';
         this.nextcloudWebDavUrl = '';
         this.nextcloudName ='Nextcloud';
@@ -122,7 +123,7 @@ export class FileSink extends ScopedElementsMixin(DBPLitElement) {
         changedProperties.forEach((oldValue, propName) => {
             switch (propName) {
                 case "lang":
-                    i18n.changeLanguage(this.lang);
+                    this._i18n.changeLanguage(this.lang);
                     break;
                 case "enabledTargets":
                     if (!this.hasEnabledDestination(this.activeTargets)) {
@@ -163,6 +164,7 @@ export class FileSink extends ScopedElementsMixin(DBPLitElement) {
     }
 
     finishedFileUpload(event) {
+        const i18n = this._i18n;
         this.sendDestination();
         MicroModal.close(this._('#modal-picker'));
         if (event.detail > 0) {
@@ -268,6 +270,7 @@ export class FileSink extends ScopedElementsMixin(DBPLitElement) {
     }
 
     getNextcloudHtml() {
+        const i18n = this._i18n;
         if (this.enabledTargets.includes('nextcloud') && this.nextcloudWebDavUrl !== "" && this.nextcloudAuthUrl !== "") {
             return html`
                 <dbp-nextcloud-file-picker id="nextcloud-file-picker"
@@ -336,7 +339,7 @@ export class FileSink extends ScopedElementsMixin(DBPLitElement) {
     }
 
     render() {
-
+        const i18n = this._i18n;
         return html`
             <vpu-notification lang="de" client-id="my-client-id"></vpu-notification>
             <div class="modal micromodal-slide" id="modal-picker" aria-hidden="true">
diff --git a/packages/file-handling/src/file-source.js b/packages/file-handling/src/file-source.js
index 0a564b41..baab4016 100644
--- a/packages/file-handling/src/file-source.js
+++ b/packages/file-handling/src/file-source.js
@@ -1,4 +1,4 @@
-import {i18n} from './i18n';
+import {createInstance} from './i18n';
 import {css, html} from 'lit-element';
 import {ScopedElementsMixin} from '@open-wc/scoped-elements';
 import DBPLitElement from '@dbp-toolkit/common/dbp-lit-element';
@@ -37,7 +37,8 @@ export class FileSource extends ScopedElementsMixin(DBPLitElement) {
     constructor() {
         super();
         this.context = '';
-        this.lang = 'de';
+        this._i18n = createInstance();
+        this.lang = this._i18n.language;
         this.nextcloudAuthUrl = '';
         this.nextcloudName ='Nextcloud';
         this.nextcloudWebDavUrl = '';
@@ -96,7 +97,7 @@ export class FileSource extends ScopedElementsMixin(DBPLitElement) {
         changedProperties.forEach((oldValue, propName) => {
             switch (propName) {
                 case "lang":
-                    i18n.changeLanguage(this.lang);
+                    this._i18n.changeLanguage(this.lang);
                     break;
                 case "enabledTargets":
                     if (!this.hasEnabledSource(this.activeTarget)) {
@@ -321,6 +322,7 @@ export class FileSource extends ScopedElementsMixin(DBPLitElement) {
 
         // no suitable files found
         if (filesToHandle.length === 0) {
+            const i18n = this._i18n;
             console.error('ZIP file does not contain any files of ' + this.allowedMimeTypes);
             //throw new Error('ZIP file does not contain any files of ' + this.allowedMimeTypes);
             notify({
@@ -541,6 +543,7 @@ export class FileSource extends ScopedElementsMixin(DBPLitElement) {
     }
 
     render() {
+        const i18n = this._i18n;
         let allowedMimeTypes = this.allowedMimeTypes;
 
         if (this.decompressZip && this.allowedMimeTypes !== "*/*") {
diff --git a/packages/file-handling/src/i18n.js b/packages/file-handling/src/i18n.js
index 498d9f03..975c1993 100644
--- a/packages/file-handling/src/i18n.js
+++ b/packages/file-handling/src/i18n.js
@@ -1,6 +1,8 @@
-import {createInstance} from '@dbp-toolkit/common/i18next.js';
+import {createInstance as _createInstance} from '@dbp-toolkit/common/i18next.js';
 
 import de from './i18n/de/translation.json';
 import en from './i18n/en/translation.json';
 
-export const i18n = createInstance({en: en, de: de}, 'de', 'en');
\ No newline at end of file
+export function createInstance() {
+    return _createInstance({en: en, de: de}, 'de', 'en');
+}
\ No newline at end of file
diff --git a/packages/file-handling/src/nextcloud-file-picker.js b/packages/file-handling/src/nextcloud-file-picker.js
index c8b2c886..14c62bb7 100644
--- a/packages/file-handling/src/nextcloud-file-picker.js
+++ b/packages/file-handling/src/nextcloud-file-picker.js
@@ -1,4 +1,4 @@
-import {i18n} from './i18n';
+import {createInstance} from './i18n';
 import {css, html} from 'lit-element';
 import {ScopedElementsMixin} from '@open-wc/scoped-elements';
 import DBPLitElement from '@dbp-toolkit/common/dbp-lit-element';
@@ -19,7 +19,9 @@ import * as fileHandlingStyles from './styles';
 export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
     constructor() {
         super();
-        this.lang = 'de';
+        this._i18n = createInstance();
+        this.lang = this._i18n.language;
+        
         this.authUrl = '';
         this.webDavUrl = '';
         this.nextcloudName = 'Nextcloud';
@@ -37,7 +39,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
         this.loading = false;
         this._onReceiveWindowMessage = this.onReceiveWindowMessage.bind(this);
 
-        this.folderIsSelected = i18n.t('nextcloud-file-picker.load-in-folder');
+        this.folderIsSelected = this._i18n.t('nextcloud-file-picker.load-in-folder');
         this.generatedFilename = '';
         this.replaceFilename = '';
         this.customFilename = '';
@@ -97,7 +99,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
         changedProperties.forEach((oldValue, propName) => {
             switch (propName) {
                 case "lang":
-                    i18n.changeLanguage(this.lang);
+                    this._i18n.changeLanguage(this.lang);
                     break;
                 case "directoriesOnly":
                     if (this.directoriesOnly && this._("#select_all_wrapper")) {
@@ -136,6 +138,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
     connectedCallback() {
         super.connectedCallback();
         const that = this;
+        const i18n = this._i18n;
         this.updateComplete.then(() => {
             // see: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
             window.addEventListener('message', this._onReceiveWindowMessage);
@@ -377,6 +380,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
     }
 
     openFilePicker() {
+        const i18n = this._i18n;
         if (this.webDavClient === null) {
             this.loading = true;
             this.statusText = i18n.t('nextcloud-file-picker.auth-progress');
@@ -428,6 +432,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
      * @param path
      */
     loadDirectory(path) {
+        const i18n = this._i18n;
         if (typeof this.directoryPath === 'undefined' || this.directoryPath === undefined) {
             this.directoryPath = '';
         }
@@ -572,6 +577,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
      * @param fileData
      */
     downloadFile(fileData) {
+        const i18n = this._i18n;
         this.loading = true;
         this.statusText = "Loading " + fileData.filename + "...";
 
@@ -602,6 +608,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
      * @param directory
      */
     sendDirectory(directory) {
+        const i18n = this._i18n;
         this.tabulatorTable.deselectRow();
         let path;
 
@@ -626,6 +633,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
      * @param directory
      */
     uploadFiles(files, directory) {
+        const i18n = this._i18n;
         this.loading = true;
         this.statusText = i18n.t('nextcloud-file-picker.upload-to', {path: directory});
         this.fileList = files;
@@ -646,6 +654,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
      * @param directory
      */
     async uploadFile(directory) {
+        const i18n = this._i18n;
         if (this.abortUpload) {
             this.abortUpload = false;
             this.abortUploadButton = false;
@@ -712,6 +721,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
      *
      */
     async uploadFileAfterConflict() {
+        const i18n = this._i18n;
         if (this.abortUpload) {
             this.abortUpload = false;
             this.abortUploadButton = false;
@@ -861,6 +871,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
      * @param directory
      */
     replaceModalDialog(file, directory) {
+        const i18n = this._i18n;
         this.uploadFileObject = file;
         this.uploadFileDirectory = directory;
         let rights = this.checkRights(file);
@@ -969,6 +980,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
      * @returns {string} correct cancel text
      */
     getCancelText() {
+        const i18n = this._i18n;
         if (this.fileList.length > 1) {
             return i18n.t('nextcloud-file-picker.replace-cancel-all');
         }
@@ -996,6 +1008,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
      *
      */
     openAddFolderDialogue() {
+        const i18n = this._i18n;
         if (this._('.addRowAnimation')) {
             this._('.addRowAnimation').classList.remove('addRowAnimation');
         }
@@ -1015,6 +1028,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
      *
      */
     addFolder() {
+        const i18n = this._i18n;
         if (this._('#new-folder').value !== "") {
             let folderName = this._('#new-folder').value;
             if (typeof this.directoryPath === 'undefined') {
@@ -1095,6 +1109,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
      * @returns {string} clickable breadcrumb path
      */
     getBreadcrumb() {
+        const i18n = this._i18n;
         if (typeof this.directoryPath === 'undefined') {
             this.directoryPath = '';
         }
@@ -1601,6 +1616,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
     }
 
     render() {
+        const i18n = this._i18n;
         const tabulatorCss = commonUtils.getAssetURL(pkgName, 'tabulator-tables/css/tabulator.min.css');
 
         return html`
-- 
GitLab