From 0217b508e5eb69032b77535023c6d92419e6abb1 Mon Sep 17 00:00:00 2001
From: Christina Toegl <toegl@tugraz.at>
Date: Sun, 28 Nov 2021 20:10:30 +0100
Subject: [PATCH] Add breadcrumb entries for favorites and recent files; split
 my recent files and all recent files; delete checkbox

---
 .../src/i18n/de/translation.json              |  12 +-
 .../src/i18n/en/translation.json              |   8 +-
 .../src/nextcloud-file-picker.js              | 415 +++++++++++++++---
 3 files changed, 373 insertions(+), 62 deletions(-)

diff --git a/packages/file-handling/src/i18n/de/translation.json b/packages/file-handling/src/i18n/de/translation.json
index b76a0579..098c2491 100644
--- a/packages/file-handling/src/i18n/de/translation.json
+++ b/packages/file-handling/src/i18n/de/translation.json
@@ -45,8 +45,8 @@
     "connect-nextcloud": "{{name}} verbinden",
     "no-data": "In diesem Ordner befinden sich keine Dateien.",
     "no-data-type": "In diesem Ordner befinden sich keine Daten vom benötigten Typ.",
-    "no-favorites": "Es wurden keine Favoriten gefunden.",
-    "no-recent-files": "Es wurden keine Dateien innerhalb der letzten 3 Monate gefunden.",
+    "no-favorites": "Es wurden keine Favoriten des entsprechenden Typs gefunden.\nDefinieren Sie in Ihrer {{name}} Dateien und Ordner als Favoriten, um diese hier anzuzeigen.",
+    "no-recent-files": "Es wurden keine Dateien entsprechenden Dateien und Ordner innerhalb der letzten 3 Monate gefunden.",
     "webdav-error": "Etwas ist schief gelaufen: {{error}}",
     "add-folder-error": "Die Ressource \"{{folder}}\", ist bereits vorhanden.",
     "add-folder-success": "Der Ordner \"{{folder}}\" wurde erfolgreich erstellt.",
@@ -78,7 +78,13 @@
     "favorites-link-text": "Meine Favoriten",
     "remember-me": "Mit {{name}} verbunden bleiben",
     "log-out": "Verbindung trennen",
-    "open-submenu": "Untermenü öffnen"
+    "open-submenu": "Untermenü öffnen",
+    "show-only-my-files": "Nur eigene Dateien zeigen",
+    "favorites-title": "Favoriten",
+    "recent-files-title": "Neueste Dateien",
+    "my-recent-files-title": "Meine neuesten Dateien",
+    "my-recent-files-link-text": "Meine neuesten Dateien",
+    "all-recent-files-link-text": "Alle neuesten Dateien"
   },
   "clipboard": {
     "add-files": "Dateien der Zwischenablage hinzufügen",
diff --git a/packages/file-handling/src/i18n/en/translation.json b/packages/file-handling/src/i18n/en/translation.json
index d6cbde72..7b6e481a 100644
--- a/packages/file-handling/src/i18n/en/translation.json
+++ b/packages/file-handling/src/i18n/en/translation.json
@@ -79,7 +79,13 @@
     "favorites-link-text": "My Favorites",
     "remember-me": "Stay connected with {{name}}",
     "log-out": "Disconnect",
-    "open-submenu": "Open submenu"
+    "open-submenu": "Open submenu",
+    "show-only-my-files": "Show only my files",
+    "favorites-title": "Favorites",
+    "recent-files-title": "Recent Files",
+    "my-recent-files-title": "My Recent Files",
+    "my-recent-files-link-text": "My Recent Files",
+    "all-recent-files-link-text": "All Recent Files"
   },
   "clipboard": {
     "add-files": "Add files to clipboard",
diff --git a/packages/file-handling/src/nextcloud-file-picker.js b/packages/file-handling/src/nextcloud-file-picker.js
index 4d88bed1..096aeffe 100644
--- a/packages/file-handling/src/nextcloud-file-picker.js
+++ b/packages/file-handling/src/nextcloud-file-picker.js
@@ -59,10 +59,11 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
         this.authInfo = '';
         this.selectBtnDisabled = true;
         this.storeSession = false;
-        this.boundCloseAdditionalMenuHandler = this.hideMoreMenu.bind(this);
+        this.boundCloseAdditionalMenuHandler = this.hideAdditionalMenu.bind(this);
         this.initateOpenAdditionalMenu = false;
         this.showAdditionalMenu = false;
         this.isInFavorites = false;
+        this.isInFilteredRecent = false;
         this.isInRecent = false;
         this.userName = '';
 
@@ -511,6 +512,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
 
     async openFilePicker() {
         const i18n = this._i18n;
+        this.disableRowClick = false;
         if (this.webDavClient === null) {
             this.loading = true;
             this.statusText = i18n.t('nextcloud-file-picker.auth-progress');
@@ -575,7 +577,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
      * @param {*} data 
      * @returns reduced list of objects, including users files
      */
-    filterUserFilesOnly(data) { //TODO verify
+    filterUserFilesOnly(data) {
         // R = Share, S = Shared Folder, M = Group folder or external source, G = Read, D = Delete, NV / NVW = Write, CK = Create
         let result = [];
 
@@ -661,7 +663,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
      *
      */
     loadFavorites() {
-        this.hideMoreMenu();
+        this.hideAdditionalMenu();
         const i18n = this._i18n;
 
         if (typeof this.directoryPath === 'undefined' || this.directoryPath === undefined) {
@@ -675,6 +677,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
         this.lastDirectoryPath = this.directoryPath;
         this.directoryPath = '';
         this.isInRecent = false;
+        this.isInFilteredRecent = false;
         this.isInFavorites = true;
                     
         if (this.webDavClient === null) {
@@ -715,7 +718,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
                     this.tabulatorTable.setData(dataObject);
 
                     if (this._('#directory-content-table').querySelector("div.tabulator-tableHolder > div.tabulator-placeholder > span")) {
-                        this._('#directory-content-table').querySelector("div.tabulator-tableHolder > div.tabulator-placeholder > span").innerText = i18n.t('nextcloud-file-picker.no-favorites');
+                        this._('#directory-content-table').querySelector("div.tabulator-tableHolder > div.tabulator-placeholder > span").innerText = i18n.t('nextcloud-file-picker.no-favorites', { name: this.nextcloudName });
                     }
 
                     this.isPickerActive = true;
@@ -748,12 +751,148 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
         });
     }
 
-    /**
+    // /**
+    //  * Loads recent files and folders from WebDAV
+    //  *
+    //  */
+    // loadRecent() {
+    //     this.hideAdditionalMenu();
+    //     const i18n = this._i18n;
+
+    //     if (typeof this.directoryPath === 'undefined' || this.directoryPath === undefined) {
+    //         this.directoryPath = '';
+    //     }
+
+    //     console.log("load recent files");
+    //     this.selectAllButton = true;
+    //     this.loading = true;
+    //     this.statusText = i18n.t('nextcloud-file-picker.loadpath-nextcloud-file-picker', {name: this.nextcloudName});
+    //     this.lastDirectoryPath = this.directoryPath;
+    //     this.directoryPath = '';
+    //     this.isInFavorites = false;
+    //     this.isInFilteredRecent = false;
+    //     this.isInRecent = true;
+
+    //     let date = new Date();
+    //     date.setMonth(date.getMonth() - 3);
+    //     let searchDate = date.toISOString().split('.')[0] + 'Z';
+
+    //     if (this.webDavClient === null || this.userName === null) {
+    //         // client is broken reload try to reset & reconnect
+    //         this.tabulatorTable.clearData();
+    //         this.webDavClient = null;
+    //         let reloadButton = html`${i18n.t('nextcloud-file-picker.something-went-wrong')} <button class="button"
+    //                         title="${i18n.t('nextcloud-file-picker.refresh-nextcloud-file-picker')}"
+    //                         @click="${async () => { this.openFilePicker(); } }"><dbp-icon name="reload"></button>`;
+    //         this.loading = false;
+    //         this.statusText = reloadButton;
+    //     }
+
+    //     //see https://github.com/perry-mitchell/webdav-client#customRequest
+    //     this.webDavClient
+    //         .customRequest('../..', { method: 'SEARCH', responseType: "text/xml", headers: { 'Content-Type': "text/xml" }, details: true, data: "<?xml version=\"1.0\" encoding='UTF-8'?>" +
+    //             "   <d:searchrequest xmlns:d=\"DAV:\" xmlns:oc=\"http://owncloud.org/ns\" xmlns:nc=\"http://nextcloud.org/ns\">" +
+    //             "       <d:basicsearch>" +
+    //             "           <d:select>" +
+    //             "               <d:prop>" +
+    //             "                   <d:getlastmodified />" +
+    //             "                   <d:resourcetype />" +
+    //             "                   <d:getcontenttype />" +
+    //             "                   <d:getcontentlength />" +
+    //             "                   <d:getetag />" +
+    //             "                   <oc:permissions />" +
+    //             "                   <oc:size/>"+
+    //             "                   <oc:owner-id/>" +
+    //             "                   <oc:owner-display-name/>" +
+    //             "               </d:prop>" +
+    //             "           </d:select>" +
+    //             "           <d:from>" +
+    //             "               <d:scope>" +
+    //             "                   <d:href>/files/" + this.userName + "/</d:href>" +
+    //             "                   <d:depth>infinity</d:depth>" +
+    //             "               </d:scope>" + 
+    //             "           </d:from>" +
+    //             "           <d:where> " +
+    //             "               <d:gte>" +
+    //             "                   <d:prop>" +
+    //             "                      <d:getlastmodified/>" +
+    //             "                   </d:prop>" +
+    //             "                   <d:literal>" + searchDate + "</d:literal>" +
+    //             "               </d:gte>" +
+    //             "           </d:where>" +
+    //             "           <d:orderby>" +
+    //             "               <d:order>" +
+    //             "                   <d:prop>" +
+    //             "                       <d:getlastmodified/>" +
+    //             "                   </d:prop>" +
+    //             "                   <d:descending/>" +
+    //             "               </d:order>" +
+    //             "           </d:orderby>" +
+    //             "           <d:limit>"+
+    //             "               <d:nresults>15</d:nresults>" +
+    //             "           </d:limit>"+
+    //             "       </d:basicsearch>" +
+    //             "   </d:searchrequest>"
+    //         })
+    //         .then(contents => {
+    //             parseXML(contents.data).then(davResp => {
+    //                 console.log('davResp', davResp);
+
+    //                 let dataObject = this.mapResponseToObject(davResp.multistatus.response);
+    //                 console.log("-contents.data-----", dataObject);
+
+    //                 if (this._("#user_files_only") && this._("#user_files_only").checked) {
+    //                     dataObject = this.filterUserFilesOnly(dataObject);
+    //                     // console.log('show only my files');
+    //                 }
+
+    //                 this.loading = false;
+    //                 this.statusText = "";
+    //                 this.tabulatorTable.setData(dataObject);
+    //                 this.tabulatorTable.setSort([
+    //                     {column: "lastmod", dir: "desc"}
+    //                 ]);
+
+    //                 if (this._('#directory-content-table').querySelector("div.tabulator-tableHolder > div.tabulator-placeholder > span")) {
+    //                     this._('#directory-content-table').querySelector("div.tabulator-tableHolder > div.tabulator-placeholder > span").innerText = i18n.t('nextcloud-file-picker.no-recent-files');
+    //                 }
+
+    //                 this.isPickerActive = true;
+    //                 this._(".nextcloud-content").scrollTop = 0;
+    //                 this._("#download-button").setAttribute("disabled", "true");
+    //             });
+    //         }).catch(error => {
+    //             console.error(error.message);
+
+    //             // on Error: try to reload with home directory
+    //             if (this.webDavClient !== null && error.message.search("401") === -1) {
+    //                 console.log("error in load directory");
+    //                 this.directoryPath = "";
+    //                 this.loadDirectory("");
+    //             }
+    //             else {
+    //                 this.loading = false;
+    //                 this.statusText = html`<span class="error"> ${i18n.t('nextcloud-file-picker.webdav-error', {error: error.message})} </span>`;
+    //                 this.isPickerActive = false;
+    //                 this.tabulatorTable.clearData();
+    //                 this.webDavClient = null;
+    //                 let reloadButton = html`${i18n.t('nextcloud-file-picker.something-went-wrong')} <button class="button"
+    //                             title="${i18n.t('nextcloud-file-picker.refresh-nextcloud-file-picker')}"
+    //                             @click="${async () => { this.openFilePicker(); } }"><dbp-icon name="reload"></button>`;
+    //                 this.loading = false;
+    //                 this.statusText = reloadButton;
+    //             }
+
+    //             this.isInRecent = false;
+    //     });
+    // }
+
+     /**
      * Loads recent files and folders from WebDAV
      *
      */
-    loadRecent() {
-        this.hideMoreMenu();
+    loadAllRecentFiles() {
+        this.hideAdditionalMenu();
         const i18n = this._i18n;
 
         if (typeof this.directoryPath === 'undefined' || this.directoryPath === undefined) {
@@ -767,6 +906,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
         this.lastDirectoryPath = this.directoryPath;
         this.directoryPath = '';
         this.isInFavorites = false;
+        this.isInFilteredRecent = false;
         this.isInRecent = true;
 
         let date = new Date();
@@ -825,7 +965,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
                 "               </d:order>" +
                 "           </d:orderby>" +
                 "           <d:limit>"+
-                "               <d:nresults>100</d:nresults>" +
+                "               <d:nresults>15</d:nresults>" +
                 "           </d:limit>"+
                 "       </d:basicsearch>" +
                 "   </d:searchrequest>"
@@ -837,11 +977,140 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
                     let dataObject = this.mapResponseToObject(davResp.multistatus.response);
                     console.log("-contents.data-----", dataObject);
 
-                    if (this._("#user_files_only") && this._("#user_files_only").checked) {
-                        dataObject = this.filterUserFilesOnly(dataObject);
-                        // console.log('show only my files');
+                    this.loading = false;
+                    this.statusText = "";
+                    this.tabulatorTable.setData(dataObject);
+                    this.tabulatorTable.setSort([
+                        {column: "lastmod", dir: "desc"}
+                    ]);
+
+                    if (this._('#directory-content-table').querySelector("div.tabulator-tableHolder > div.tabulator-placeholder > span")) {
+                        this._('#directory-content-table').querySelector("div.tabulator-tableHolder > div.tabulator-placeholder > span").innerText = i18n.t('nextcloud-file-picker.no-recent-files');
                     }
 
+                    this.isPickerActive = true;
+                    this._(".nextcloud-content").scrollTop = 0;
+                    this._("#download-button").setAttribute("disabled", "true");
+                });
+            }).catch(error => {
+                console.error(error.message);
+
+                // on Error: try to reload with home directory
+                if (this.webDavClient !== null && error.message.search("401") === -1) {
+                    console.log("error in load directory");
+                    this.directoryPath = "";
+                    this.loadDirectory("");
+                }
+                else {
+                    this.loading = false;
+                    this.statusText = html`<span class="error"> ${i18n.t('nextcloud-file-picker.webdav-error', {error: error.message})} </span>`;
+                    this.isPickerActive = false;
+                    this.tabulatorTable.clearData();
+                    this.webDavClient = null;
+                    let reloadButton = html`${i18n.t('nextcloud-file-picker.something-went-wrong')} <button class="button"
+                                title="${i18n.t('nextcloud-file-picker.refresh-nextcloud-file-picker')}"
+                                @click="${async () => { this.openFilePicker(); } }"><dbp-icon name="reload"></button>`;
+                    this.loading = false;
+                    this.statusText = reloadButton;
+                }
+
+                this.isInRecent = false;
+        });
+    }
+
+     /**
+     * Loads recent files and folders from WebDAV
+     *
+     */
+    loadMyRecentFiles() {
+        this.hideAdditionalMenu();
+        const i18n = this._i18n;
+
+        if (typeof this.directoryPath === 'undefined' || this.directoryPath === undefined) {
+            this.directoryPath = '';
+        }
+
+        console.log("load recent files");
+        this.selectAllButton = true;
+        this.loading = true;
+        this.statusText = i18n.t('nextcloud-file-picker.loadpath-nextcloud-file-picker', {name: this.nextcloudName});
+        this.lastDirectoryPath = this.directoryPath;
+        this.directoryPath = '';
+        this.isInFavorites = false;
+        this.isInRecent = false;
+        this.isInFilteredRecent = true;
+
+        let date = new Date();
+        date.setMonth(date.getMonth() - 3);
+        let searchDate = date.toISOString().split('.')[0] + 'Z';
+
+        if (this.webDavClient === null || this.userName === null) {
+            // client is broken reload try to reset & reconnect
+            this.tabulatorTable.clearData();
+            this.webDavClient = null;
+            let reloadButton = html`${i18n.t('nextcloud-file-picker.something-went-wrong')} <button class="button"
+                            title="${i18n.t('nextcloud-file-picker.refresh-nextcloud-file-picker')}"
+                            @click="${async () => { this.openFilePicker(); } }"><dbp-icon name="reload"></button>`;
+            this.loading = false;
+            this.statusText = reloadButton;
+        }
+
+        //see https://github.com/perry-mitchell/webdav-client#customRequest
+        this.webDavClient
+            .customRequest('../..', { method: 'SEARCH', responseType: "text/xml", headers: { 'Content-Type': "text/xml" }, details: true, data: "<?xml version=\"1.0\" encoding='UTF-8'?>" +
+                "   <d:searchrequest xmlns:d=\"DAV:\" xmlns:oc=\"http://owncloud.org/ns\" xmlns:nc=\"http://nextcloud.org/ns\">" +
+                "       <d:basicsearch>" +
+                "           <d:select>" +
+                "               <d:prop>" +
+                "                   <d:getlastmodified />" +
+                "                   <d:resourcetype />" +
+                "                   <d:getcontenttype />" +
+                "                   <d:getcontentlength />" +
+                "                   <d:getetag />" +
+                "                   <oc:permissions />" +
+                "                   <oc:size/>"+
+                "                   <oc:owner-id/>" +
+                "                   <oc:owner-display-name/>" +
+                "               </d:prop>" +
+                "           </d:select>" +
+                "           <d:from>" +
+                "               <d:scope>" +
+                "                   <d:href>/files/" + this.userName + "/</d:href>" +
+                "                   <d:depth>infinity</d:depth>" +
+                "               </d:scope>" + 
+                "           </d:from>" +
+                "           <d:where> " +
+                "               <d:gte>" +
+                "                   <d:prop>" +
+                "                      <d:getlastmodified/>" +
+                "                   </d:prop>" +
+                "                   <d:literal>" + searchDate + "</d:literal>" +
+                "               </d:gte>" +
+                "           </d:where>" +
+                "           <d:orderby>" +
+                "               <d:order>" +
+                "                   <d:prop>" +
+                "                       <d:getlastmodified/>" +
+                "                   </d:prop>" +
+                "                   <d:descending/>" +
+                "               </d:order>" +
+                "           </d:orderby>" +
+                "           <d:limit>"+
+                "               <d:nresults>15</d:nresults>" +
+                "           </d:limit>"+
+                "       </d:basicsearch>" +
+                "   </d:searchrequest>"
+            })
+            .then(contents => {
+                parseXML(contents.data).then(davResp => {
+                    console.log('davResp', davResp);
+
+                    let dataObject = this.mapResponseToObject(davResp.multistatus.response);
+                    console.log("-contents.data-----", dataObject);
+
+                    // show only current user files
+                    dataObject = this.filterUserFilesOnly(dataObject);
+
                     this.loading = false;
                     this.statusText = "";
                     this.tabulatorTable.setData(dataObject);
@@ -879,7 +1148,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
                     this.statusText = reloadButton;
                 }
 
-                this.isInRecent = false;
+                this.isInFilteredRecent = false;
         });
     }
 
@@ -889,7 +1158,8 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
      * @param path
      */
     loadDirectory(path) {
-        this.hideMoreMenu();
+        this.hideAdditionalMenu();
+        
         const i18n = this._i18n;
         if (typeof this.directoryPath === 'undefined' || this.directoryPath === undefined) {
             this.directoryPath = '';
@@ -898,6 +1168,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
             path = '';
         }
 
+        this.disableRowClick = false;
         this.loading = true;
         this.statusText = i18n.t('nextcloud-file-picker.loadpath-nextcloud-file-picker', {name: this.nextcloudName});
         this.lastDirectoryPath = this.directoryPath;
@@ -1518,18 +1789,12 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
         this._('#new-folder-row').querySelector("div.tabulator-cell:nth-child(1) > div > span.tabulator-responsive-collapse-toggle-open").classList.add('new-folder-selected');
         this._('#new-folder-row').querySelector("div.tabulator-cell:nth-child(1) > div > span.tabulator-responsive-collapse-toggle-close").classList.add('new-folder-selected');
 
-        // this._('#directory-content-table').querySelector("div.tabulator-tableHolder > div.tabulator-table > div.tabulator-row:nth-child(1) > div.tabulator-cell:nth-child(3)")
-        //     .classList.add('blinking');
-
         this._('#new-folder-row').querySelector("div.tabulator-cell:nth-child(6)").innerText = '';
         this._('#new-folder-row').querySelector("div.tabulator-cell:nth-child(3)").setAttribute('id', 'new-folder-cell');
 
         // add text input field
         this._('#new-folder-cell').innerHTML = '<input type="text" class="input" name="tf-new-folder" id ="tf-new-folder" value="" placeholder="'+ i18n.t('nextcloud-file-picker.new-folder-placeholder') + '" />';
 
-        // set focus to text field
-        // this._('#tf-new-folder').focus(); //TODO does it work?
-
         // add event listener for pressing enter to save new folder with given name
         this._('#tf-new-folder').addEventListener("keyup", ({key}) => {
             if (key === "Enter") {
@@ -1538,6 +1803,18 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
             }
         })
 
+        this._('#tf-new-folder').addEventListener("keyup", ({key}) => {
+            if (key === "Escape") {
+                console.log('ESC pressed');
+                // TODO abbrechen
+            }
+        })
+
+        this._('#tf-new-folder').addEventListener("click", ({key}) => {
+            //TODO add click rules
+        })
+
+
         // during folder creation it should not be possible to click something
         this.disableRowClick = true;
 
@@ -1547,7 +1824,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
             row.getElement().classList.remove("tabulator-selectable");
         })
 
-
+        // set focus to text field
         // this._('#tf-new-folder').focus();
     }
 
@@ -1710,20 +1987,38 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
         htmlpath[0] = html`<span class="breadcrumb"><a class="home-link" @click="${() => {
             this.loadDirectory("");
         }}" title="${i18n.t('nextcloud-file-picker.folder-home')}"><dbp-icon name="home"></dbp-icon> </a></span>`;
-        const directories = this.directoryPath.split('/');
-        if (directories[1] === "") {
-            return htmlpath;
-        }
-        for (let i = 1; i < directories.length; i++) {
-            let path = "";
-            for (let j = 1; j <= i; j++) {
-                path += "/";
-                path += directories[j];
-            }
+        
+        if (this.isInFavorites) {
+            htmlpath[1] = html`<span> › </span><span class="breadcrumb"><a @click="${() => {
+                this.loadDirectory(path);
+            }}" title="${i18n.t('nextcloud-file-picker.favorites-title')}">${i18n.t('nextcloud-file-picker.favorites-title')}</a></span>`;
+
+        } else if (this.isInRecent) {
+            htmlpath[1] = html`<span> › </span><span class="breadcrumb"><a @click="${() => {
+                this.loadDirectory(path);
+            }}" title="${i18n.t('nextcloud-file-picker.recent-files-title')}">${i18n.t('nextcloud-file-picker.recent-files-title')}</a></span>`;
 
-            htmlpath[i] = html`<span> › </span><span class="breadcrumb"><a @click="${() => {
+        } else if (this.isInFilteredRecent) { 
+            htmlpath[1] = html`<span> › </span><span class="breadcrumb"><a @click="${() => {
                 this.loadDirectory(path);
-            }}" title="${i18n.t('nextcloud-file-picker.load-path-link', {path: directories[i]})}">${directories[i]}</a></span>`;
+            }}" title="${i18n.t('nextcloud-file-picker.my-recent-files-title')}">${i18n.t('nextcloud-file-picker.my-recent-files-title')}</a></span>`;
+        
+        } else { // case normal folders
+            const directories = this.directoryPath.split('/');
+            if (directories[1] === "") {
+                return htmlpath;
+            }
+            for (let i = 1; i < directories.length; i++) {
+                let path = "";
+                for (let j = 1; j <= i; j++) {
+                    path += "/";
+                    path += directories[j];
+                }
+
+                htmlpath[i] = html`<span> › </span><span class="breadcrumb"><a @click="${() => {
+                    this.loadDirectory(path);
+                }}" title="${i18n.t('nextcloud-file-picker.load-path-link', {path: directories[i]})}">${directories[i]}</a></span>`;
+            }
         }
 
         return htmlpath;
@@ -1777,7 +2072,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
         }
     }
 
-    hideMoreMenu() {
+    hideAdditionalMenu() {
         if (this.initateOpenAdditionalMenu) {
             this.initateOpenAdditionalMenu = false;
             return;
@@ -1797,6 +2092,11 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
             ${commonStyles.getRadioAndCheckboxCss()}
             ${fileHandlingStyles.getFileHandlingCss()}
 
+            .button-container.filter-user {
+                line-height: 28px;
+                padding-left: 40px;
+            }
+
             .tabulator-row.no-select.tabulator-selected {
                 background-color: white;
                 color: #333;
@@ -1867,13 +2167,12 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
                 padding-right: 0px;
                 padding-top: 10px;
                 padding-bottom: 10px;
-                padding-left: 0px;
+                padding-left: 4px; /** align with */
             }
 
             .extended-menu li {
                 padding: 7px;
                 padding-right: 46px;
-                // border-bottom: 1px solid #f3f3f3; //deleted in JF 08.11.2021
             }
 
             .extended-menu li.active {
@@ -1907,13 +2206,6 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
                 color: #E4154B;
             }
 
-            // ul.extended-menu li.close { //deleted in JF 08.11.2021
-            //     display: block;
-            //     padding: 7px 15px 7px 15px;
-            //     text-align: right;
-            //     cursor: pointer;
-            // }
-
             .nextcloud-header {
                 margin-bottom: 2rem;
                 display: inline-grid;
@@ -2005,9 +2297,8 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
 
             .additional-menu {
                 white-space: nowrap;
-                // align-self: end; //deleted in JF 08.11.2021
                 height: 33px;
-                margin-right: 5px;
+                margin-right: 10px; /** 5px */
             }
 
             .nextcloud-nav p {
@@ -2259,11 +2550,9 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
             }
 
             .more-menu {
-                // height: 22.4px; //deleted in JF 08.11.2021
-                // width: 22.4px;
-                // top: 8px;
                 height: 22.4px;
-                top: 4px;
+                /*top: 4px;*/
+                width: 19px;
             }
 
             .nextcloud-nav a.home-link {
@@ -2464,7 +2753,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
                         <div class="additional-menu ${classMap({hidden: !this.showAdditionalMenu})}">
 
                             <a class="extended-menu-link" @click="${() => { this.toggleMoreMenu(); }}" title="${i18n.t('nextcloud-file-picker.more-menu')}">
-                                <dbp-icon name="menu-dots" class="more-menu"></dbp-icon> <!-- instead of name="more-filled" ; deleted in JF 08.11.2021-->
+                                <dbp-icon name="menu-dots" class="more-menu"></dbp-icon>
                             </a>
                             <ul class='extended-menu hidden'>
                                 <li class="${classMap({active: this.isInFavorites})}" id="favorites-item">
@@ -2472,13 +2761,23 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
                                         ${i18n.t('nextcloud-file-picker.favorites-link-text')}
                                     </a>
                                 </li>
-                                <li class="${classMap({active: this.isInRecent})}" id="recent-item">
+                                <!-- <li class="${classMap({active: this.isInRecent})}" id="recent-item">
                                     <a class="" @click="${this.loadRecent}">
                                         ${i18n.t('nextcloud-file-picker.recent-files-link-text')}
                                     </a>
+                                </li> -->
+                                <li class="${classMap({active: this.isInFilteredRecent})}" id="my-recent-item">
+                                    <a class="" @click="${this.loadMyRecentFiles}">
+                                        ${i18n.t('nextcloud-file-picker.my-recent-files-link-text')}
+                                    </a>
+                                </li>
+                                <li class="${classMap({active: this.isInRecent})}" id="all-recent-item">
+                                    <a class="" @click="${this.loadAllRecentFiles}">
+                                        ${i18n.t('nextcloud-file-picker.all-recent-files-link-text')}
+                                    </a>
                                 </li>
                                 <li class="${classMap({hidden: !this.directoriesOnly})}">
-                                    <a class="${classMap({inactive: this.isInRecent || this.isInFavorites || this.disableRowClick})}" @click="${() => { this.addOpenFolderTableEntry(); }}">
+                                    <a class="${classMap({inactive: this.isInRecent || this.isInFavorites || this.isInFilteredRecent || this.disableRowClick})}" @click="${() => { this.addOpenFolderTableEntry(); }}">
                                         ${i18n.t('nextcloud-file-picker.add-folder')}
                                     </a>
                                 </li>
@@ -2507,7 +2806,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
                             </button>
                             
                                 <li class="${classMap({hidden: !this.storeSession})}" title="${i18n.t('nextcloud-file-picker.log-out')}">
-                                    <a class="" @click="${() => { this.logOut(); this.hideMoreMenu(); }}">
+                                    <a class="" @click="${() => { this.logOut(); this.hideAdditionalMenu(); }}">
                                         ${i18n.t('nextcloud-file-picker.log-out')}
                                     </a>
                                 </li>
@@ -2535,14 +2834,14 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
 
                         </div>
                     </div> 
-                <!--TODO replace mode all checkbox place-->
-                    <div class="filter-options-wrapper ${classMap({hidden: !this.isInRecent})}">
-                        <label id="user-files-only-wrapper" class="button-container">
-                        <!-- ${i18n.t('nextcloud-file-picker.replace-mode-all')} --> Zeige nur eigene Dateien <!--TODO-->
-                            <input type="checkbox" id="user_files_only" name="user_files_only" value="user_files_only" > <!--@click="${() => { this.filterUserFilesOnly(); }}"-->
+                <!--TODO find filter-user-files-only checkbox place DELETED in JF 23.11.2021 -->
+                    <!-- <div class="filter-options-wrapper ${classMap({hidden: !this.isInRecent})}">
+                        <label id="user-files-only-wrapper" class="button-container filter-user">
+                        ${i18n.t('nextcloud-file-picker.show-only-my-files')}
+                            <input type="checkbox" id="user_files_only" name="user_files_only" value="user_files_only" checked @click="${() => { this.loadRecent(); }}">
                             <span class="checkmark" id="user_files_only_checkmark"></span>
                         </label>
-                    </div>
+                    </div> -->
                     <div class="table-wrapper">
                         <table id="directory-content-table" class="force-no-select"></table>
                     </div>
-- 
GitLab