import {createInstance} from './i18n';
import {css, html} from 'lit';
import {ScopedElementsMixin} from '@open-wc/scoped-elements';
import DBPLitElement from '@dbp-toolkit/common/dbp-lit-element';
import {Icon, MiniSpinner, getShadowRootDocument} from '@dbp-toolkit/common';
import * as commonUtils from '@dbp-toolkit/common/utils';
import * as commonStyles from '@dbp-toolkit/common/styles';
import {createClient, parseXML} from 'webdav/web';
import {classMap} from 'lit/directives/class-map.js';
import {humanFileSize} from '@dbp-toolkit/common/i18next';
import {TabulatorFull as Tabulator} from 'tabulator-tables';
import MicroModal from './micromodal.es';
import {name as pkgName} from './../package.json';
import * as fileHandlingStyles from './styles';
import {encrypt, decrypt, parseJwt} from './crypto.js';

/**
 * NextcloudFilePicker web component
 */
export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
    constructor() {
        super();
        this._i18n = createInstance();
        this.lang = this._i18n.language;

        this.auth = {};
        this.authUrl = '';
        this.webDavUrl = '';
        this.nextcloudName = 'Nextcloud';
        this.nextcloudFileURL = '';
        this.loginWindow = null;
        this.isPickerActive = false;
        this.statusText = '';
        this.lastDirectoryPath = '/';
        this.directoryPath = '';
        this.webDavClient = null;
        this.tabulatorTable = null;
        this.allowedMimeTypes = '';
        this.directoriesOnly = false;
        this.maxSelectedItems = Number.MAX_VALUE;
        this.loading = false;
        this._onReceiveWindowMessage = this.onReceiveWindowMessage.bind(this);

        this.folderIsSelected = this._i18n.t('nextcloud-file-picker.load-in-folder');
        this.generatedFilename = '';
        this.replaceFilename = '';
        this.customFilename = '';
        this.uploadFileObject = null;
        this.uploadFileDirectory = null;
        this.fileList = [];
        this.fileNameCounter = 1;
        this.activeDirectoryRights = 'RGDNVCK';
        this.activeDirectoryACL = '';
        this.forAll = false;
        this.uploadCount = 0;
        this.abortUploadButton = false;
        this.abortUpload = false;
        this.authInfo = '';
        this.selectBtnDisabled = true;
        this.storeSession = false;
        this.boundCloseAdditionalMenuHandler = this.hideAdditionalMenu.bind(this);
        this.initateOpenAdditionalMenu = false;
        this.isInFavorites = false;
        this.isInFilteredRecent = false;
        this.isInRecent = false;
        this.userName = '';
        this.menuHeightBreadcrumb = -1;

        this.boundCloseBreadcrumbMenuHandler = this.hideBreadcrumbMenu.bind(this);
        this.initateOpenBreadcrumbMenu = false;

        this.boundClickOutsideNewFolderHandler = this.deleteNewFolderEntry.bind(this);
        this.initateOpenNewFolder = false;

        this.disableRowClick = false;
        this.boundRefreshOnWindowSizeChange = this.refreshOnWindowSizeChange.bind(this);
        this.boundCancelNewFolderHandler = this.cancelNewFolder.bind(this);
        this.boundSelectHandler = this.selectAllFiles.bind(this);
    }

    static get scopedElements() {
        return {
            'dbp-icon': Icon,
            'dbp-mini-spinner': MiniSpinner,
        };
    }

    /**
     * See: https://lit-element.polymer-project.org/guide/properties#initialize
     */
    static get properties() {
        return {
            ...super.properties,
            lang: {type: String},
            auth: {type: Object},
            authUrl: {type: String, attribute: 'auth-url'},
            webDavUrl: {type: String, attribute: 'web-dav-url'},
            nextcloudFileURL: {type: String, attribute: 'nextcloud-file-url'},
            nextcloudName: {type: String, attribute: 'nextcloud-name'},
            isPickerActive: {type: Boolean, attribute: false},
            statusText: {type: String, attribute: false},
            folderIsSelected: {type: String, attribute: false},
            authInfo: {type: String, attribute: 'auth-info'},
            directoryPath: {type: String, attribute: 'directory-path'},
            allowedMimeTypes: {type: String, attribute: 'allowed-mime-types'},
            directoriesOnly: {type: Boolean, attribute: 'directories-only'},
            maxSelectedItems: {type: Number, attribute: 'max-selected-items'},
            loading: {type: Boolean, attribute: false},
            replaceFilename: {type: String, attribute: false},
            uploadFileObject: {type: Object, attribute: false},
            uploadFileDirectory: {type: String, attribute: false},
            activeDirectoryRights: {type: String, attribute: false},
            activeDirectoryACL: {type: String, attribute: false},
            abortUploadButton: {type: Boolean, attribute: false},
            selectBtnDisabled: {type: Boolean, attribute: true},
            userName: {type: Boolean, attribute: false},
            storeSession: {type: Boolean, attribute: 'store-nextcloud-session'},
            disableRowClick: {type: Boolean, attribute: false},
        };
    }

    update(changedProperties) {
        changedProperties.forEach((oldValue, propName) => {
            switch (propName) {
                case 'lang':
                    this._i18n.changeLanguage(this.lang);
                    break;
                case 'auth':
                    this._updateAuth();
                    break;
                case 'directoriesOnly':
                    if (this.directoriesOnly && this._('#select_all_wrapper')) {
                        this._('#select_all_wrapper').classList.remove('button-container');
                        this._('#select_all_wrapper').classList.add('hidden');
                    }
                    if (!this.directoriesOnly && this._('#select_all_wrapper')) {
                        this._('#select_all_wrapper').classList.add('button-container');
                        this._('#select_all_wrapper').classList.remove('hidden');
                    }
            }
        });

        super.update(changedProperties);
    }

    disconnectedCallback() {
        window.removeEventListener('message', this._onReceiveWindowMessage);
        window.removeEventListener('resize', this.boundRefreshOnWindowSizeChange);

        // deregister tabulator table callback events
        this.tabulatorTable.off("tableBuilt");
        this.tabulatorTable.off("rowSelectionChanged");
        this.tabulatorTable.off("rowClick");
        this.tabulatorTable.off("rowAdded");
        this.tabulatorTable.off("dataLoaded");
        super.disconnectedCallback();
    }

    connectedCallback() {
        super.connectedCallback();
        const that = this;
        const i18n = this._i18n;
        this._loginStatus = '';
        this._loginState = [];
        this._loginCalled = false;

        this.updateComplete.then(() => {
            // see: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
            window.addEventListener('message', this._onReceiveWindowMessage);
            // see: http://tabulator.info/docs/5.1
            this.tabulatorTable = new Tabulator(this._('#directory-content-table'), {
                layout: 'fitColumns',
                selectable: this.maxSelectedItems,
                placeholder: this.directoriesOnly
                    ? i18n.t('nextcloud-file-picker.no-data')
                    : i18n.t('nextcloud-file-picker.no-data-type'),
                responsiveLayout: 'collapse',
                responsiveLayoutCollapseStartOpen: false,
                columnDefaults: {
                    vertAlign: 'middle',
                    hozAlign: 'left',
                    resizable: false,
                },
                columns: [
                    {
                        minWidth: 40,
                        headerSort: false,
                        formatter: 'responsiveCollapse',
                    },
                    {
                        title:
                            '<label id="select_all_wrapper" class="button-container select-all-icon">' +
                            '<input type="checkbox" id="select_all" name="select_all" value="select_all">' +
                            '<span class="checkmark" id="select_all_checkmark"></span>' +
                            '</label>',

                        field: 'type',
                        hozAlign: 'center',
                        width: 50,
                        headerSort: false,
                        responsive: 1,
                        formatter: (cell, formatterParams, onRendered) => {
                            const icon_tag = that.getScopedTagName('dbp-icon');
                            let disabled = this.directoriesOnly
                                ? 'nextcloud-picker-icon-disabled'
                                : '';
                            let icon =
                                `<${icon_tag} name="empty-file" class="nextcloud-picker-icon ` +
                                disabled +
                                `"></${icon_tag}>`;
                            let html =
                                cell.getValue() === 'directory'
                                    ? `<${icon_tag} name="folder" class="nextcloud-picker-icon"></${icon_tag}>`
                                    : icon;
                            let div = getShadowRootDocument(this).createElement('div');
                            div.innerHTML = html;
                            return div;
                        },
                    },
                    {
                        title: i18n.t('nextcloud-file-picker.filename'),
                        responsive: 0,
                        widthGrow: 5,
                        minWidth: 150,
                        field: 'basename',
                        sorter: 'alphanum',
                        formatter: (cell) => {
                            var data = cell.getValue();
                            let div = getShadowRootDocument(this).createElement('div');
                            div.classList.add('filename');
                            div.innerHTML = cell.getValue();
                            return div;
                        },
                    },
                    {
                        title: i18n.t('nextcloud-file-picker.size'),
                        responsive: 4,
                        widthGrow: 1,
                        minWidth: 84,
                        field: 'size',
                        formatter: (cell, formatterParams, onRendered) => {
                            return cell.getRow().getData().type === 'directory'
                                ? ''
                                : humanFileSize(cell.getValue());
                        },
                    },
                    {
                        title: i18n.t('nextcloud-file-picker.mime-type'),
                        responsive: 2,
                        widthGrow: 1,
                        minWidth: 58,
                        field: 'mime',
                        formatter: (cell, formatterParams, onRendered) => {
                            if (typeof cell.getValue() === 'undefined') {
                                return '';
                            }
                            const [, fileSubType] = cell.getValue().split('/');
                            return fileSubType;
                        },
                    },
                    {
                        title: i18n.t('nextcloud-file-picker.last-modified'),
                        responsive: 3,
                        widthGrow: 1,
                        minWidth: 150,
                        field: 'lastmod',
                        sorter: (a, b, aRow, bRow, column, dir, sorterParams) => {
                            const a_timestamp = Date.parse(a);
                            const b_timestamp = Date.parse(b);
                            return a_timestamp - b_timestamp;
                        },
                        formatter: function (cell, formatterParams, onRendered) {
                            const d = Date.parse(cell.getValue());
                            const timestamp = new Date(d);
                            const year = timestamp.getFullYear();
                            const month = ('0' + (timestamp.getMonth() + 1)).slice(-2);
                            const date = ('0' + timestamp.getDate()).slice(-2);
                            const hours = ('0' + timestamp.getHours()).slice(-2);
                            const minutes = ('0' + timestamp.getMinutes()).slice(-2);
                            return date + '.' + month + '.' + year + ' ' + hours + ':' + minutes;
                        },
                    },
                    {title: 'rights', field: 'props.permissions', visible: false},
                    {title: 'acl', field: 'props.acl-list.acl.acl-permissions', visible: false},
                ],
                initialSort: [
                    {column: 'basename', dir: 'asc'},
                    {column: 'type', dir: 'asc'},
                ],
                rowFormatter: (row) => {
                    let data = row.getData();
                    if (!this.checkFileType(data, this.allowedMimeTypes)) {
                        row.getElement().classList.add('no-select'); // TODO check this
                        row.getElement().classList.remove('tabulator-selectable');
                    }
                    if (this.directoriesOnly && typeof data.mime !== 'undefined') {
                        row.getElement().classList.add('no-select');
                        row.getElement().classList.remove('tabulator-selectable');
                    }

                    if (!this.directoriesOnly && typeof data.mime === 'undefined') {
                        row.getElement().classList.add('no-select-styles');
                    }
                },
            });

            this.tabulatorTable.on("tableBuilt", this.tableBuiltFunction.bind(this));
            this.tabulatorTable.on("rowSelectionChanged", this.rowSelectionChangedFunction.bind(this));
            this.tabulatorTable.on("rowClick", this.rowClickFunction.bind(this));
            this.tabulatorTable.on("rowAdded", this.rowAddedFunction.bind(this));
            this.tabulatorTable.on("dataLoaded", this.dataLoadedFunction.bind(this));

            if (
                typeof this.allowedMimeTypes !== 'undefined' &&
                this.allowedMimeTypes !== '' &&
                !this.directoriesOnly
            ) {
                this.tabulatorTable.setFilter(this.checkFileType, this.allowedMimeTypes);
            }

            window.addEventListener('resize', this.boundRefreshOnWindowSizeChange);
        });
    }

    tableBuiltFunction() {
        if (this._('#select_all')) {
            this._('#select_all').addEventListener('click', this.boundSelectHandler);
        }
        if (this.directoriesOnly && this._('#select_all_wrapper')) {
            this._('#select_all_wrapper').classList.remove('button-container');
            this._('#select_all_wrapper').classList.add('hidden');
        }
    }

    rowSelectionChangedFunction(data, rows) {
        const i18n = this._i18n;

        if (!this.disableRowClick) {
            if (data.length > 0 && this.directoriesOnly) {
                this.folderIsSelected = i18n.t('nextcloud-file-picker.load-to-folder');
            } else {
                this.folderIsSelected = i18n.t('nextcloud-file-picker.load-in-folder');
            }
            if (
                !this.directoriesOnly &&
                this.tabulatorTable &&
                this.tabulatorTable
                    .getSelectedRows()
                    .filter(
                        (row) =>
                            row.getData().type != 'directory' &&
                            this.checkFileType(row.getData(), this.allowedMimeTypes)
                    ).length > 0
            ) {
                this.selectBtnDisabled = false;
            } else {
                this.selectBtnDisabled = true;
            }
            if (this._('#select_all_checkmark')) {
                this._('#select_all_checkmark').title = this.checkAllSelected()
                    ? i18n.t('clipboard.select-nothing')
                    : i18n.t('clipboard.select-all');
            }
            this.requestUpdate();
        }
    }

    rowClickFunction(e, row) {
        const i18n = this._i18n;
        const data = row.getData();
        if (
            !row.getElement().classList.contains('no-select') &&
            !this.disableRowClick
        ) {
            if (this.directoriesOnly) {
                // comment out if you want to navigate through folders with double click
                const data = row.getData();
                this.directoryClicked(e, data);
                this.folderIsSelected = i18n.t('nextcloud-file-picker.load-in-folder');
            } else {
                switch (data.type) {
                    case 'directory':
                        this.directoryClicked(e, data);
                        break;
                    case 'file':
                        if (
                            this.tabulatorTable !== null &&
                            this.tabulatorTable.getSelectedRows().length ===
                            this.tabulatorTable
                                .getRows()
                                .filter(
                                    (row) =>
                                        row.getData().type != 'directory' &&
                                        this.checkFileType(
                                            row.getData(),
                                            this.allowedMimeTypes
                                        )
                                ).length
                        ) {
                            this._('#select_all').checked = true;
                        } else {
                            this._('#select_all').checked = false;
                        }
                        break;
                }
            }
        } else {
            row.deselect();
        }
    }

    rowAddedFunction(row) {
        if (!this.disableRowClick) {
            row.getElement().classList.toggle('addRowAnimation');
        }
    }

    dataLoadedFunction(data) {
        if (this.tabulatorTable !== null) {
            const that = this;
            setTimeout(function () {
                if (that._('.tabulator-responsive-collapse-toggle-open')) {
                    that._a('.tabulator-responsive-collapse-toggle-open').forEach(
                        (element) =>
                            element.addEventListener(
                                'click',
                                that.toggleCollapse.bind(that)
                            )
                    );
                }

                if (that._('.tabulator-responsive-collapse-toggle-close')) {
                    that._a('.tabulator-responsive-collapse-toggle-close').forEach(
                        (element) =>
                            element.addEventListener(
                                'click',
                                that.toggleCollapse.bind(that)
                            )
                    );
                }
            }, 0);

        }
    }

    /**
     *  Request a re-render every time isLoggedIn()/isLoading() changes
     */
    _updateAuth() {
        this._loginStatus = this.auth['login-status'];

        let newLoginState = [this.isLoggedIn(), this.isLoading()];

        if (this._loginState.toString() !== newLoginState.toString()) {
            this.requestUpdate();
        }

        this._loginState = newLoginState;

        if (this.isLoggedIn() && !this._loginCalled) {
            this._loginCalled = true;
            this.checkLocalStorage();
        }
    }

    /**
     * Returns if a person is set in or not
     *
     * @returns {boolean} true or false
     */
    isLoggedIn() {
        return this.auth.person !== undefined && this.auth.person !== null;
    }

    /**
     * Returns true if a person has successfully logged in
     *
     * @returns {boolean} true or false
     */
    isLoading() {
        if (this._loginStatus === 'logged-out') return false;

        return !this.isLoggedIn() && this.auth.token !== undefined;
    }

    /**
     *
     */
    async checkLocalStorage() {
        if (!this.isLoggedIn() || !this.auth) {
            for (let key of Object.keys(localStorage)) {
                if (
                    key.includes('nextcloud-webdav-username-') ||
                    key.includes('nextcloud-webdav-password-')
                ) {
                    localStorage.removeItem(key);
                }
            }
            return;
        }
        const publicId = this.auth['person-id'];
        const token = parseJwt(this.auth.token);
        const sessionId = token ? token.sid : '';

        if (
            this.storeSession &&
            sessionId &&
            localStorage.getItem('nextcloud-webdav-username-' + publicId) &&
            localStorage.getItem('nextcloud-webdav-password-' + publicId)
        ) {
            try {
                const userName = await decrypt(
                    sessionId,
                    localStorage.getItem('nextcloud-webdav-username-' + publicId)
                );
                const password = await decrypt(
                    sessionId,
                    localStorage.getItem('nextcloud-webdav-password-' + publicId)
                );
                this.webDavClient = createClient(this.webDavUrl + '/' + userName, {
                    username: userName,
                    password: password,
                });

                this.userName = userName;

                this.isPickerActive = true;
                this.loadDirectory(this.directoryPath);
            } catch (e) {
                localStorage.removeItem('nextcloud-webdav-username-' + publicId);
                localStorage.removeItem('nextcloud-webdav-password-' + publicId);
                return;
            }
        }
    }

    /**
     * check mime type of row
     *
     * @param data
     * @param filterParams
     */
    checkFileType(data, filterParams) {
        if (filterParams === '') return true;
        if (typeof data.mime === 'undefined') {
            return true;
        }
        const [fileMainType, fileSubType] = data.mime.split('/');
        const mimeTypes = filterParams.split(',');
        let deny = true;

        mimeTypes.forEach((str) => {
            const [mainType, subType] = str.split('/');
            deny =
                deny &&
                ((mainType !== '*' && mainType !== fileMainType) ||
                    (subType !== '*' && subType !== fileSubType));
        });

        return !deny;
    }

    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');
            const authUrl =
                this.authUrl + '?target-origin=' + encodeURIComponent(window.location.href);
            this.loginWindow = window.open(
                authUrl,
                'Nextcloud Login',
                'width=400,height=400,menubar=no,scrollbars=no,status=no,titlebar=no,toolbar=no'
            );
        } else {
            this.loadDirectory(this.directoryPath, this.webDavClient);
        }
    }

    _a(selector) {
        return this.shadowRoot === null
            ? this.querySelectorAll(selector)
            : this.shadowRoot.querySelectorAll(selector);
    }

    async onReceiveWindowMessage(event) {
        if (this.webDavClient === null) {
            const data = event.data;

            if (data.type === 'webapppassword') {
                if (this.loginWindow !== null) {
                    this.loginWindow.close();
                }

                // See https://github.com/perry-mitchell/webdav-client/blob/master/API.md#module_WebDAV.createClient
                this.webDavClient = createClient(
                    data.webdavUrl || this.webDavUrl + '/' + data.loginName,
                    {
                        username: data.loginName,
                        password: data.token,
                    }
                );

                if (
                    this.storeSession &&
                    this.isLoggedIn() &&
                    this._('#remember-checkbox') &&
                    this._('#remember-checkbox').checked
                ) {
                    const publicId = this.auth['person-id'];
                    const token = parseJwt(this.auth.token);
                    const sessionId = token ? token.sid : '';
                    if (sessionId) {
                        const encrytedName = await encrypt(sessionId, data.loginName);
                        const encrytedToken = await encrypt(sessionId, data.token);
                        localStorage.setItem('nextcloud-webdav-username-' + publicId, encrytedName);
                        localStorage.setItem(
                            'nextcloud-webdav-password-' + publicId,
                            encrytedToken
                        );
                    }
                }

                this.loadDirectory(this.directoryPath);
                this.userName = data.loginName;
            }
        }
    }

    toggleCollapse(e) {
        const table = this.tabulatorTable;
        // give a chance to draw the table
        // this is for getting more hight in tabulator table, when toggle is called
        setTimeout(function () {
            table.redraw();
        }, 0);
    }

    /**
     *
     * @param {*} data
     * @returns {Array} reduced list of objects, including users files
     */
    filterUserFilesOnly(data) {
        // R = Share, S = Shared Folder, M = Group folder or external source, G = Read, D = Delete, NV / NVW = Write, CK = Create
        let result = [];

        for (let i = 0; i < data.length; i++) {
            if (data) {
                let file_perm = data[i].props.permissions;
                if (!file_perm.includes('M') && !file_perm.includes('S')) {
                    result.push(data[i]);
                }
            }
        }

        return result;
    }

    /**
     *
     * @param {*} path
     * @returns {Array} including file path and base name
     */
    parseFileAndBaseName(path) {
        if (path[0] !== '/') {
            //TODO verify
            path = '/' + path;
        }
        while (/^.+\/$/.test(path)) {
            path = path.substr(0, path.length - 1);
        }
        path = decodeURIComponent(path);

        let array1 = this.webDavUrl.split('/');
        let array2 = path.split('/');
        for (let i = 0; i < array2.length; i++) {
            let item2 = array2[i];
            array1.forEach((item1) => {
                if (item1 === item2) {
                    array2.shift();
                    i--;
                }
            });
        }
        array2.shift();

        let basename = array2[array2.length - 1];
        let filename = '/' + array2.join('/');

        return [filename, basename];
    }

    /**
     *
     * @param {*} response
     * @returns {Array} list of file objects containing corresponding information
     */
    mapResponseToObject(response) {
        let results = [];

        response.forEach((item) => {
            const [filePath, baseName] = this.parseFileAndBaseName(item.href);

            const prop = item.propstat.prop;
            let etag = typeof prop.getetag === 'string' ? prop.getetag.replace(/"/g, '') : null;
            let sizeVal = prop.getcontentlength ? prop.getcontentlength : '0';
            let fileType =
                prop.resourcetype &&
                typeof prop.resourcetype === 'object' &&
                typeof prop.resourcetype.collection !== 'undefined'
                    ? 'directory'
                    : 'file';

            let mimeType;
            if (fileType === 'file') {
                mimeType =
                    prop.getcontenttype && typeof prop.getcontenttype === 'string'
                        ? prop.getcontenttype.split(';')[0]
                        : '';
            }

            let propsObject = {
                getetag: etag,
                getlastmodified: prop.getlastmodified,
                getcontentlength: sizeVal,
                permissions: prop.permissions,
                resourcetype: fileType,
                getcontenttype: prop.getcontenttype,
            };

            let statObject = {
                basename: baseName,
                etag: etag,
                filename: filePath,
                lastmod: prop.getlastmodified,
                mime: mimeType,
                props: propsObject,
                size: parseInt(sizeVal, 10),
                type: fileType,
            };

            results.push(statObject);
        });

        return results;
    }

    /**
     * Loads the favorites from WebDAV
     *
     */
    loadFavorites() {
        this.hideAdditionalMenu();
        const i18n = this._i18n;

        if (typeof this.directoryPath === 'undefined' || this.directoryPath === undefined) {
            this.directoryPath = '';
        }

        console.log('load nextcloud favorites');
        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.isInRecent = false;
        this.isInFilteredRecent = false;
        this.isInFavorites = true;

        if (this.webDavClient === 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: 'REPORT',
                responseType: 'text/xml',
                details: true,
                data:
                    '<?xml version="1.0"?>' +
                    '   <oc:filter-files  xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns" xmlns:nc="http://nextcloud.org/ns">' +
                    '       <oc:filter-rules>' +
                    '           <oc:favorite>1</oc:favorite>' +
                    '       </oc:filter-rules>' +
                    '       <d:prop>' +
                    '           <d:getlastmodified />' +
                    '           <d:resourcetype />' +
                    '           <d:getcontenttype />' +
                    '           <d:getcontentlength />' +
                    '           <d:getetag />' +
                    '           <oc:permissions />' +
                    '        </d:prop>' +
                    '   </oc:filter-files>',
            })
            .then((contents) => {
                parseXML(contents.data).then((davResp) => {
                    // console.log("-contents.data-----", davResp);
                    let dataObject = this.mapResponseToObject(davResp.multistatus.response);

                    this.loading = false;
                    this.statusText = '';
                    this.tabulatorTable.setData(dataObject);
                    this.tabulatorTable.setSort([
                        {column: "basename", dir: "asc"},
                        {column: "type", dir: "asc"},
                    ]);

                    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', {
                            name: this.nextcloudName,
                        });
                    }

                    this.isPickerActive = true;
                    this._('.nextcloud-content').scrollTop = 0;
                    this._('#download-button').setAttribute('disabled', 'true');
                });
            })
            .catch((error) => {
                //TODO verify error catching
                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.isInFavorites = false;
            });
    }

    /**
     * Loads recent files and folders from WebDAV
     *
     */
    loadAllRecentFiles() {
        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);

                    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 only my 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);
                    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.isInFilteredRecent = false;
            });
    }

    /**
     * Loads the directory from WebDAV
     *
     * @param path
     */
    loadDirectory(path) {
        this.hideAdditionalMenu();

        const i18n = this._i18n;
        if (typeof this.directoryPath === 'undefined' || this.directoryPath === undefined) {
            this.directoryPath = '';
        }
        if (path === undefined) {
            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;
        this.directoryPath = path;
        if (this._('#select_all')) this._('#select_all').checked = false;

        // see https://github.com/perry-mitchell/webdav-client#getdirectorycontents
        if (this.webDavClient === 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"></dbp-icon>
                </button>
            `;
            this.loading = false;
            this.statusText = reloadButton;
        }
        this.webDavClient
            .getDirectoryContents(path, {
                details: true,
                data:
                    '<?xml version="1.0"?>' +
                    '<d:propfind  xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns" xmlns:nc="http://nextcloud.org/ns"  xmlns:ocs="http://open-collaboration-services.org/ns">' +
                    '  <d:prop>' +
                    '        <d:getlastmodified />' +
                    '        <d:resourcetype />' +
                    '        <d:getcontenttype />' +
                    '        <d:getcontentlength />' +
                    '        <d:getetag />' +
                    '        <oc:permissions />' +
                    '        <nc:acl-list>' +
                    '           <nc:acl>' +
                    '               <nc:acl-permissions />' +
                    '           </nc:acl>' +
                    '        </nc:acl-list>' +
                    '  </d:prop>' +
                    '</d:propfind>',
            })
            .then((contents) => {
                this.loading = false;
                this.statusText = '';
                this.tabulatorTable.setData(contents.data);
                this.tabulatorTable.setSort([
                    {column: "basename", dir: "asc"},
                    {column: "type", dir: "asc"},
                ]);
                this.isPickerActive = true;
                this.isInFavorites = false;
                this.isInRecent = false;
                this.isInFilteredRecent = false;
                this._('.nextcloud-content').scrollTop = 0;
                if (
                    !this.activeDirectoryRights.includes('CK') &&
                    !this.activeDirectoryRights.includes('NV')
                ) {
                    this._('#download-button').setAttribute('disabled', 'true');
                } else {
                    this._('#download-button').removeAttribute('disabled');
                }
                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 = this.directoriesOnly
                        ? i18n.t('nextcloud-file-picker.no-data')
                        : i18n.t('nextcloud-file-picker.no-data-type');
                }
            })
            .catch((error) => {
                console.error(error.message);

                // on Error: try to reload with home directory
                if (
                    path !== '/' &&
                    path !== '' &&
                    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"></dbp-icon>
                        </button>
                    `;
                    this.loading = false;
                    this.statusText = reloadButton;
                }
            });
    }

    /**
     * Event Triggered when a directory in tabulator table is clicked
     *
     * @param event
     * @param file
     */
    directoryClicked(event, file) {
        // save rights of clicked directory
        if (typeof file.props !== 'undefined') {
            this.activeDirectoryRights = file.props.permissions;
            if (
                typeof file.props['acl-list'] !== 'undefined' &&
                typeof file.props['acl-list']['acl']['acl-permissions'] !== 'undefined' &&
                file.props['acl-list']['acl']['acl-permissions']
            ) {
                this.activeDirectoryACL = file.props['acl-list']['acl']['acl-permissions'];
            } else {
                this.activeDirectoryACL = '';
            }
        } else {
            this.activeDirectoryRights = 'SGDNVCK';
        }
        this.loadDirectory(file.filename);
        event.preventDefault();
    }

    /**
     * Download all files
     *
     * @param files
     */
    downloadFiles(files) {
        files.forEach((fileData) => this.downloadFile(fileData, files.length));

        this.tabulatorTable.deselectRow();
        if (this._('#select_all')) {
            this._('#select_all').checked = false;
        }
        const data = {count: files.length};
        const event = new CustomEvent('dbp-nextcloud-file-picker-number-files', {
            detail: data,
            bubbles: true,
            composed: true,
        });
        this.dispatchEvent(event);

        if (files.length > 0) {
            this.sendSetPropertyEvent('analytics-event', {
                category: 'FileHandlingNextcloud',
                action: 'DownloadFiles',
                name: files.length,
            });
        }
    }

    /**
     * Download a single file
     *
     * @param fileData
     * @param maxUpload
     */
    downloadFile(fileData, maxUpload) {
        const i18n = this._i18n;
        this.loading = true;
        this.statusText = 'Loading ' + fileData.filename + '...';

        // https://github.com/perry-mitchell/webdav-client#getfilecontents
        this.webDavClient
            .getFileContents(fileData.filename)
            .then((contents) => {
                // create file to send via event
                const file = new File([contents], fileData.basename, {type: fileData.mime});
                // send event
                const data = {file: file, data: fileData, maxUpload: maxUpload};
                const event = new CustomEvent('dbp-nextcloud-file-picker-file-downloaded', {
                    detail: data,
                    bubbles: true,
                    composed: true,
                });
                this.dispatchEvent(event);
                this.loading = false;
                this.statusText = '';
            })
            .catch((error) => {
                console.error(error.message);
                this.loading = false;
                this.statusText = html`
                    <span class="error">
                        ${i18n.t('nextcloud-file-picker.webdav-error', {error: error.message})}
                    </span>
                `;
            });
    }

    /**
     * Send the directory to filesink
     *
     * @param directory
     */
    sendDirectory(directory) {
        const i18n = this._i18n;

        if (this.isInFavorites) {
            this.statusText = html`
                <span class="error">
                    ${i18n.t('nextcloud-file-picker.error-save-to-favorites')}
                </span>
            `;
            return;
        } else if (this.isInRecent || this.isInFilteredRecent) {
            this.statusText = html`
                <span class="error">${i18n.t('nextcloud-file-picker.error-save-to-recent')}</span>
            `;
            return;
        }

        this.tabulatorTable.deselectRow();
        let path;

        if (!directory[0]) {
            path = this.directoryPath;
        } else {
            path = directory[0].filename;
        }
        this.loading = true;
        this.statusText = i18n.t('nextcloud-file-picker.upload-to', {path: path});

        const event = new CustomEvent('dbp-nextcloud-file-picker-file-uploaded', {
            detail: path,
            bubbles: true,
            composed: true,
        });
        this.dispatchEvent(event);
    }

    /**
     * Upload Files to a directory
     *
     * @param files
     * @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];
        if (this.fileList !== undefined && this.fileList.length > 0) {
            this.sendSetPropertyEvent('analytics-event', {
                category: 'FileHandlingNextcloud',
                action: 'UploadFiles',
                name: files.length,
            });
        }
        this.forAll = false;
        this.setRepeatForAllConflicts();
        this.uploadFile(directory);
    }

    /**
     * Upload a single file from this.filelist to given directory
     *
     * @param directory
     */
    async uploadFile(directory) {
        const i18n = this._i18n;
        if (this.abortUpload) {
            this.abortUpload = false;
            this.abortUploadButton = false;
            this.forAll = false;
            this.loading = false;
            this.statusText = i18n.t('nextcloud-file-picker.abort-message');
            this._('#replace_mode_all').checked = false;
            return;
        }
        if (this.fileList.length !== 0) {
            let file = this.fileList[0];
            this.replaceFilename = file.name;
            let path = directory + '/' + file.name;
            // https://github.com/perry-mitchell/webdav-client#putfilecontents
            let that = this;
            this.loading = true;
            this.statusText = i18n.t('nextcloud-file-picker.upload-to', {path: path});
            // contentLength: https://github.com/perry-mitchell/webdav-client/issues/266
            await this.webDavClient
                .putFileContents(path, file, {
                    contentLength: file.size,
                    overwrite: false
                })
                .then(function (success) {
                    if (!success) {
                        that.generatedFilename = that.getNextFilename();
                        that._('#replace-filename').value = that.generatedFilename;
                        if (that.forAll) {
                            that.uploadFileObject = file;
                            that.uploadFileDirectory = directory;
                            that.abortUploadButton = true;
                            that.uploadFileAfterConflict();
                        } else {
                            that.replaceModalDialog(file, directory);
                        }
                    } else {
                        that.uploadCount += 1;
                        that.fileList.shift();
                        that.uploadFile(directory);
                    }
                })
                .catch((error) => {
                    throw error;
                });
        } else {
            this.loadDirectory(this.directoryPath);
            this.loading = false;
            this.statusText = '';
            this._('#replace_mode_all').checked = false;
            this.forAll = false;
            this.customFilename = '';
            const event = new CustomEvent('dbp-nextcloud-file-picker-file-uploaded-finished', {
                bubbles: true,
                composed: true,
                detail: this.uploadCount,
            });
            this.uploadCount = 0;
            this.abortUpload = false;
            this.abortUploadButton = false;
            this.dispatchEvent(event);
        }
    }

    /**
     * Upload a file after a conflict happens on webdav side
     *
     */
    async uploadFileAfterConflict() {
        const i18n = this._i18n;
        if (this.abortUpload) {
            this.abortUpload = false;
            this.abortUploadButton = false;
            this.forAll = false;
            this.loading = false;
            this.statusText = i18n.t('nextcloud-file-picker.abort-message');
            this._('#replace_mode_all').checked = false;
            return;
        }
        let path = '';
        let overwrite = false;
        let file = this.uploadFileObject;
        let directory = this.uploadFileDirectory;

        if (this._("input[name='replacement']:checked").value === 'ignore') {
            MicroModal.close(this._('#replace-modal'));
            this.forAll ? (this.fileList = []) : this.fileList.shift();
            this.uploadFile(directory);
            return true;
        } else if (this._("input[name='replacement']:checked").value === 'new-name') {
            if (this.generatedFilename !== this._('#replace-filename').value) {
                this.customFilename = this._('#replace-filename').value;
            }
            path = directory + '/' + this._('#replace-filename').value;
            MicroModal.close(this._('#replace-modal'));
            this.replaceFilename = this._('#replace-filename').value;
        } else {
            path = directory + '/' + this.uploadFileObject.name;
            overwrite = true;
        }

        this.loading = true;
        this.statusText = i18n.t('nextcloud-file-picker.upload-to', {path: path});

        let that = this;
        // https://github.com/perry-mitchell/webdav-client#putfilecontents
        // contentLength: https://github.com/perry-mitchell/webdav-client/issues/266
        await this.webDavClient
            .putFileContents(path, file, {
                contentLength: file.size,
                overwrite: overwrite,
                onUploadProgress: (progress) => {
                    /*console.log(`Uploaded ${progress.loaded} bytes of ${progress.total}`);*/
                },
            })
            .then((content) => {
                MicroModal.close(this._('#replace-modal'));
                this.uploadCount += 1;
                that.fileList.shift();
                that.uploadFile(directory);
            })
            .catch((error) => {
                if (error.message.search('412') !== -1) {
                    MicroModal.close(that._('#replace-modal'));
                    this.generatedFilename = this.getNextFilename();
                    this._('#replace-filename').value = this.generatedFilename;
                    if (this.forAll) {
                        this.uploadFileObject = file;
                        this.uploadFileDirectory = directory;
                        this.abortUploadButton = true;
                        this.uploadFileAfterConflict();
                    } else {
                        this.replaceModalDialog(file, directory);
                    }
                } else {
                    throw error;
                }
            });

        this.fileNameCounter = 1;
    }

    /**
     * Check permissions of a given file in the active directory
     * no rename: if you dont have create permissions
     * no replace: if you dont have write permissions
     *
     * R = Share, S = Shared Folder, M = Group folder or external source, G = Read, D = Delete, NV / NVW = Write, CK = Create
     *
     * @param file
     * @returns {number}
     */
    checkRights(file) {
        // nextcloud permissions
        let file_perm = 0;
        let active_directory_perm = this.activeDirectoryRights;
        let rows = this.tabulatorTable.searchRows('basename', '=', this.replaceFilename);
        if (typeof rows[0] !== 'undefined' && rows[0]) {
            file_perm = rows[0].getData().props.permissions;
        } else {
            file_perm = '';
        }

        /* ACL permissions: If ACL > permssions comment this in
        if (this.activeDirectoryACL !== '') {
            console.log("ACL SET");
            active_directory_perm = "MG";
            if (this.activeDirectoryACL & (1 << (3 - 1))) {
                active_directory_perm = "CK";
                console.log("ACL CREATE");
            }
            if (this.activeDirectoryACL & (1 << (2 - 1))) {
                active_directory_perm += "NV";
                console.log("ACL WRITE");
            }
        }

        // if file has acl rights take that
        if (typeof rows[0].getData().props['acl-list'] !== 'undefined' && rows[0].getData().props['acl-list'] &&
            rows[0].getData().props['acl-list']['acl']['acl-permissions'] !== '') {
            console.log("FILE HAS ACL");
            file_perm = "MG";

            if (rows[0].getData().props['acl-list']['acl']['acl-permissions'] & (1 << (3 - 1))) {
                file_perm = "CK";
                console.log("FILE ACL CREATE");
            }
            if (rows[0].getData().props['acl-list']['acl']['acl-permissions'] & (1 << (2 - 1))) {
                file_perm += "NV";
                console.log("FILE ACL WRITE");
            }
        }
        */

        // all allowed
        if (active_directory_perm.includes('CK') && file_perm.includes('NV')) {
            return -1;
        }

        // read only file but you can write to directory = only create and no edit
        if (active_directory_perm.includes('CK') && !file_perm.includes('NV')) {
            return 1;
        }

        // only edit and no create
        if (!active_directory_perm.includes('CK') && file_perm.includes('NV')) {
            return 2;
        }

        // read only directory and read only file
        return 0;
    }

    /**
     * Open the replace Modal Dialog with gui where forbidden actions are disabled
     *
     * @param file
     * @param directory
     */
    replaceModalDialog(file, directory) {
        const i18n = this._i18n;
        this.uploadFileObject = file;
        this.uploadFileDirectory = directory;
        let rights = this.checkRights(file);
        // read only directory or read only file
        if (rights === 0) {
            this.loading = false;
            this.statusText = i18n.t('nextcloud-file-picker.readonly');
            return;
        }
        // read only file but you can write to directory = only create and no edit
        else if (rights === 1) {
            this.loading = false;
            this.statusText = i18n.t('nextcloud-file-picker.onlycreate');
            this._('#replace-replace').setAttribute('disabled', 'true');
            this._('#replace-new-name').removeAttribute('disabled');
            this._('#replace-replace').checked = false;
            this._('#replace-new-name').checked = true;
            this.setInputFieldVisibility();
            this._('#replace-new-name').focus();
        }
        // only edit and no create
        else if (rights === 2) {
            this.loading = false;
            this.statusText = i18n.t('nextcloud-file-picker.onlyedit');
            this._('#replace-new-name').setAttribute('disabled', 'true');
            this._('#replace-replace').removeAttribute('disabled');
            this._('#replace-new-name').checked = false;
            this._('#replace-replace').checked = true;
            this.setInputFieldVisibility();
            this._('#replace-replace').focus();
        }
        // all allowed
        else {
            this._('#replace-new-name').removeAttribute('disabled');
            this._('#replace-replace').removeAttribute('disabled');
            this._('#replace-replace').checked = false;
            this._('#replace-new-name').checked = true;
            this.setInputFieldVisibility();
            this._('#replace-new-name').focus();
        }
        MicroModal.show(this._('#replace-modal'), {
            disableScroll: true,
            onClose: (modal) => {
                this.statusText = '';
                this.loading = false;
            },
        });
    }

    closeDialog(e) {
        if (this.tabulatorTable) {
            this.tabulatorTable.deselectRow();
        }
        if (this._('#select_all')) {
            this._('#select_all').checked = false;
        }
        MicroModal.close(this._('#modal-picker'));
    }

    /**
     * Returns a filename with the next counter number.
     *
     * @returns {string} The next filename
     */
    getNextFilename() {
        let nextFilename = '';
        let splitFilename;
        if (this.forAll && this.customFilename !== '') {
            splitFilename = this.customFilename.split('.');
        } else {
            splitFilename = this.replaceFilename.split('.');
        }

        let splitBracket = splitFilename[0].split('(');
        if (splitBracket.length > 1) {
            let numberString = splitBracket[1].split(')');
            if (numberString.length > 1 && !isNaN(parseInt(numberString[0]))) {
                let number = parseInt(numberString[0]);
                this.fileNameCounter = number + 1;
                nextFilename = splitBracket[0] + '(' + this.fileNameCounter + ')';
            } else {
                nextFilename = splitFilename[0] + '(' + this.fileNameCounter + ')';
            }
        } else {
            nextFilename = splitFilename[0] + '(' + this.fileNameCounter + ')';
        }
        if (splitFilename.length > 1) {
            for (let i = 1; i < splitFilename.length; i++) {
                nextFilename = nextFilename + '.' + splitFilename[i];
            }
        }
        this.fileNameCounter++;
        return nextFilename;
    }

    /**
     * Disables or enables the input field for the new file name
     */
    setInputFieldVisibility() {
        this._('#replace-filename').disabled = !this._('#replace-new-name').checked;
    }

    /**
     * Returns text for the cancel button depending on number of files
     *
     * @returns {string} correct cancel text
     */
    getCancelText() {
        const i18n = this._i18n;
        if (this.fileList.length > 1) {
            return i18n.t('nextcloud-file-picker.replace-cancel-all');
        }
        return i18n.t('nextcloud-file-picker.replace-cancel');
    }

    /**
     *
     */
    cancelOverwrite() {
        this.statusText = '';
        this.loading = false;
        this.fileList = [];
    }

    /**
     *
     */
    setRepeatForAllConflicts() {
        this.forAll = this._('#replace_mode_all').checked;
    }

    /**
     * Add new folder with webdav
     *
     */
    openAddFolderDialogue() {
        const i18n = this._i18n;
        if (this._('.addRowAnimation')) {
            this._('.addRowAnimation').classList.remove('addRowAnimation');
        }
        this._('#new-folder-wrapper').classList.toggle('hidden');
        if (this._('#new-folder-wrapper').classList.contains('hidden')) {
            this._('#add-folder-button').setAttribute('name', 'plus');
            this._('#add-folder-button').setAttribute(
                'title',
                i18n.t('nextcloud-file-picker.add-folder-open')
            );
        } else {
            this._('#add-folder-button').setAttribute('name', 'close');
            this._('#add-folder-button').setAttribute(
                'title',
                i18n.t('nextcloud-file-picker.add-folder-close')
            );
            this._('#new-folder').focus();
        }
    }

    /**
     * Opens new folder modal
     *
     */
    addOpenFolderTableEntry() {
        // Avoid row animation for previously created folders
        if (this._('.addRowAnimation')) {
            this._('.addRowAnimation').classList.remove('addRowAnimation');
        }

        this.disableRowClick = true;

        // Click handler should ignore first click
        this.initateOpenNewFolder = true;

        // Give the browser a chance to paint before selecting
        setTimeout(() => {
            this._('#tf-new-folder-dialog').select();
        }, 0);

        MicroModal.show(this._('#new-folder-modal'), {
            disableScroll: true,
        });

        this._('#tf-new-folder-dialog').addEventListener('keydown', ({key}) => { //TODO since we do not destroy the modal it is enough to do this once
            if (key === 'Enter') {
                this.addNewFolder();
            }
        });

        this._('#new-folder-modal-box').addEventListener('click', (event) => { //TODO same here?
            event.stopPropagation();
        });

        document.addEventListener('keydown', this.boundCancelNewFolderHandler);

        // during folder creation it should not be possible to click something
        document.addEventListener('click', this.boundClickOutsideNewFolderHandler);
    }

    cancelNewFolder(event) {
        if (event.key === 'Escape') {
            this.deleteNewFolderEntry();
            event.stopPropagation();
        }
    }

    deleteNewFolderEntry() {
        const i18n = this._i18n;

        if (this.initateOpenNewFolder) {
            this.initateOpenNewFolder = false;
            return;
        }

        this.disableRowClick = false;
        MicroModal.close(this._('#new-folder-modal'));

        document.removeEventListener('click', this.boundClickOutsideNewFolderHandler);
        document.removeEventListener('keydown', this.boundCancelNewFolderHandler);
        this._('#tf-new-folder-dialog').value = i18n.t('nextcloud-file-picker.new-folder-dialog-default-name');
    }

    addNewFolder() {
        const i18n = this._i18n;
        if (this._('#tf-new-folder-dialog').value !== '') {
            let folderName = this._('#tf-new-folder-dialog').value;
            if (typeof this.directoryPath === 'undefined') {
                this.directoryPath = '';
            }
            this.deleteNewFolderEntry();

            let folderPath = this.directoryPath + '/' + folderName;
            this.webDavClient
                .createDirectory(folderPath)
                .then((contents) => {
                    this.tabulatorTable.setSort();
                    const d = new Date();
                    let props = {permissions: 'RGDNVCK'};
                    this.tabulatorTable.addRow(
                        {
                            type: 'directory',
                            filename: folderPath,
                            basename: folderName,
                            lastmod: d,
                            props: props,
                        },
                        true
                    );
                    this.statusText = i18n.t('nextcloud-file-picker.add-folder-success', {
                        folder: folderName,
                    });
                    this.loading = false;
                })
                .catch((error) => {
                    this.loading = false;
                    if (error.message.search('405') !== -1) {
                        this.statusText = html`
                            <span class="error">
                                ${i18n.t('nextcloud-file-picker.add-folder-error', {
                                    folder: folderName,
                                })}
                            </span>
                        `;
                    } else {
                        this.statusText = html`
                            <span class="error">
                                ${i18n.t('nextcloud-file-picker.webdav-error', {
                            error: error.message,
                        })}
                            </span>
                        `;
                    }
                });
        } else {
            this.statusText = html`
                <span class="error">${i18n.t('nextcloud-file-picker.add-folder-error-empty')}</span>
            `;
        }
    }

    /**
     * Add new folder with webdav
     *
     */
    addFolder() {
        const i18n = this._i18n;
        if (this._('#new-folder').value !== '') {
            let folderName = this._('#new-folder').value;
            if (typeof this.directoryPath === 'undefined') {
                this.directoryPath = '';
            }
            let folderPath = this.directoryPath + '/' + folderName;
            this.webDavClient
                .createDirectory(folderPath)
                .then((contents) => {
                    // this.loadDirectory(this.directoryPath);
                    this.tabulatorTable.setSort();
                    const d = new Date();
                    let props = {permissions: 'RGDNVCK'};
                    this.tabulatorTable.addRow(
                        {
                            type: 'directory',
                            filename: folderPath,
                            basename: folderName,
                            lastmod: d,
                            props: props,
                        },
                        true
                    );
                    this.statusText = i18n.t('nextcloud-file-picker.add-folder-success', {
                        folder: folderName,
                    });
                    this.loading = false;
                })
                .catch((error) => {
                    this.loading = false;
                    if (error.message.search('405') !== -1) {
                        this.statusText = html`
                            <span class="error">
                                ${i18n.t('nextcloud-file-picker.add-folder-error', {
                                    folder: folderName,
                                })}
                            </span>
                        `;
                    } else {
                        this.statusText = html`
                            <span class="error">
                                ${i18n.t('nextcloud-file-picker.webdav-error', {
                                    error: error.message,
                                })}
                            </span>
                        `;
                    }
                });

            this._('#new-folder').value = '';
            this.openAddFolderDialogue();
        }
    }

    /**
     * Select or deselect all files from tabulator table
     *
     */
    selectAllFiles() {
        let allSelected = this.checkAllSelected();

        if (allSelected) {
            this.tabulatorTable.getSelectedRows().forEach((row) => row.deselect());
        } else {
            this.tabulatorTable.selectRow(
                this.tabulatorTable
                    .getRows()
                    .filter(
                        (row) =>
                            row.getData().type != 'directory' &&
                            this.checkFileType(row.getData(), this.allowedMimeTypes)
                    )
            );
        }
    }

    checkAllSelected() {
        if (this.tabulatorTable) {
            let maxSelected = this.tabulatorTable
                .getRows()
                .filter(
                    (row) =>
                        row.getData().type != 'directory' &&
                        this.checkFileType(row.getData(), this.allowedMimeTypes)
                ).length;
            let selected = this.tabulatorTable.getSelectedRows().length;
            if (selected === maxSelected) {
                return true;
            }
        }
        return false;
    }

    logOut() {
        this.webDavClient = null;
        this.isPickerActive = false;
        if (this.auth) {
            const publicId = this.auth['person-id'];
            localStorage.removeItem('nextcloud-webdav-username' + publicId);
            localStorage.removeItem('nextcloud-webdav-password' + publicId);
        }
    }

    /**
     * Returns the directory path as clickable breadcrumbs
     *
     * @returns {string} clickable breadcrumb path
     */
    getBreadcrumb() {
        const i18n = this._i18n;
        if (typeof this.directoryPath === 'undefined') {
            this.directoryPath = '';
        }
        let htmlpath = [];
        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>
        `;

        if (this.isInFavorites) {
            htmlpath[1] = html`
                <span class="first">›</span>
                <span class="breadcrumb special">
                    <a
                            @click="${() => {
                                this.loadFavorites();
                            }}"
                            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 class="first">›</span>
                <span class="breadcrumb special">
                    <a
                            @click="${() => {
                                this.loadAllRecentFiles();
                            }}"
                            title="${i18n.t('nextcloud-file-picker.recent-files-title')}">
                        ${i18n.t('nextcloud-file-picker.recent-files-title')}
                    </a>
                </span>
            `;
        } else if (this.isInFilteredRecent) {
            htmlpath[1] = html`
                <span class="first">›</span>
                <span class="breadcrumb special">
                    <a
                            @click="${() => {
                                this.loadMyRecentFiles();
                            }}"
                            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];
                }

                if (i === 1) {
                    htmlpath[i] = html`
                        <span class="first breadcrumb-arrow">›</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>
                    `;
                } else {
                    htmlpath[i] = html`
                        <span class="breadcrumb-arrow">›</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>
                    `;
                }
            }

            let length = htmlpath.length;
            let width = window.innerWidth;

            if (length > 3 && width <= 768) {
                //breadcrumb longer than 3 && only for mobile view

                let path_temp = [];

                // for (let i = 2; i < htmlpath.length - 1; i++) {
                //     path_temp[i] = html`<li class="breadcrumb-${i}" id="breadcrumb-${i}">${htmlpath[i]}</li>`;
                // }

                for (let i = 1; i < directories.length - 1; i++) {
                    let path = '';
                    for (let j = 1; j <= i; j++) {
                        path += '/';
                        path += directories[j];
                    }

                    path_temp[i] = html`
                        <li class="breadcrumb-${i}" id="breadcrumb-${i}">
                            <a
                                    @click="${() => {
                                        this.loadDirectory(path);
                                    }}"
                                    title="${i18n.t('nextcloud-file-picker.load-path-link', {
                                        path: directories[i],
                                    })}">
                                <dbp-icon name="folder" class="breadcrumb-folder"></dbp-icon>
                                ${directories[i]}
                            </a>
                        </li>
                    `;
                }

                let shortcrumb = [];

                shortcrumb[0] = htmlpath[0];
                shortcrumb[1] = html`
                    <span class="first breadcrumb-arrow">›</span>
                    <span class="breadcrumb">
                        <a
                                class="extended-breadcrumb-link"
                                @click="${() => {
                                    this.toggleBreadcrumbMenu();
                                }}">
                            . . .
                        </a>
                        <div class="breadcrumb-menu">
                            <ul class="extended-breadcrumb-menu hidden">
                                ${path_temp}
                            </ul>
                        </div>
                    </span>
                `;

                shortcrumb[2] = htmlpath[length - 1];

                return shortcrumb;
            }
        }

        return htmlpath;
    }

    toggleBreadcrumbMenu() {
        const menu = this.shadowRoot.querySelector('ul.extended-breadcrumb-menu');
        const menuStart = this.shadowRoot.querySelector('a.extended-breadcrumb-link');

        if (menu === null || menuStart === null) {
            return;
        }

        menu.classList.toggle('hidden'); //sets hidden or removes it

        // computations for overflow - begin
        this.menuHeightBreadcrumb = menu.clientHeight;

        let topValue = menuStart.getBoundingClientRect().bottom;
        let topHeight = this._('.nextcloud-header').offsetHeight;
        let isMenuOverflow =
            this.menuHeightBreadcrumb + topHeight >= this._('.wrapper').offsetHeight ? true : false;

        //set max-width to window with
        let maxWidth = this._('.wrapper').offsetWidth;

        if (isMenuOverflow && !menu.classList.contains('hidden')) {
            let actualHeight =
                this._('.wrapper').offsetHeight - this._('.nextcloud-nav').offsetHeight;
            menu.setAttribute(
                'style',
                'position: fixed;top: ' +
                topValue +
                'px;height: ' +
                actualHeight +
                'px;max-width: ' +
                maxWidth +
                'px;overflow-y: auto;'
            );
            menu.scrollTop = 0;
            this._('.nextcloud-content').setAttribute('style', 'overflow:hidden;');
        } else if (isMenuOverflow && menu.classList.contains('hidden')) {
            this._('.nextcloud-content').removeAttribute('style', 'overflow:hidden;');
            menu.removeAttribute('style');
        }
        // computations for overflow - end

        if (!menu.classList.contains('hidden')) {
            // add event listener for clicking outside of menu
            if (!isMenuOverflow) {
                menu.setAttribute('style', 'max-width: ' + maxWidth + 'px;');
            }
            document.addEventListener('click', this.boundCloseBreadcrumbMenuHandler);
            this.initateOpenBreadcrumbMenu = true;
        } else {
            document.removeEventListener('click', this.boundCloseBreadcrumbMenuHandler);
            this._('.nextcloud-content').removeAttribute('style', 'overflow:hidden;');
            menu.removeAttribute('style');
        }
    }

    hideBreadcrumbMenu() {
        if (this.initateOpenBreadcrumbMenu) {
            this.initateOpenBreadcrumbMenu = false;
            return;
        }
        const menu = this.shadowRoot.querySelector('ul.extended-breadcrumb-menu');
        if (menu && !menu.classList.contains('hidden')) this.toggleBreadcrumbMenu();
    }

    refreshOnWindowSizeChange() {
        this.requestUpdate();
    }

    /**
     * Returns Link to Nextcloud with actual directory
     *
     * @returns {string} actual directory Nextcloud link
     */
    getNextCloudLink() {
        return this.nextcloudFileURL + this.directoryPath;
    }

    toggleMoreMenu() {
        const menu = this.shadowRoot.querySelector('ul.extended-menu');
        const menuStart = this.shadowRoot.querySelector('a.extended-menu-link');

        if (menu === null || menuStart === null) {
            return;
        }

        menu.classList.toggle('hidden');

        if (!menu.classList.contains('hidden')) {
            // add event listener for clicking outside of menu
            document.addEventListener('click', this.boundCloseAdditionalMenuHandler);
            this.initateOpenAdditionalMenu = true;
        } else {
            document.removeEventListener('click', this.boundCloseAdditionalMenuHandler);
        }
    }

    hideAdditionalMenu() {
        if (this.initateOpenAdditionalMenu) {
            this.initateOpenAdditionalMenu = false;
            return;
        }
        const menu = this.shadowRoot.querySelector('ul.extended-menu');
        if (menu && !menu.classList.contains('hidden')) this.toggleMoreMenu();
    }

    _atChangeInput(event) {
        if (this._("#new-folder-confirm-btn"))
            this._("#new-folder-confirm-btn").disabled = this._('#tf-new-folder-dialog') && this._('#tf-new-folder-dialog').value === '';
    }

    static get styles() {
        // language=css
        return css`
            ${commonStyles.getGeneralCSS()}
            ${commonStyles.getButtonCSS()}
            ${commonStyles.getTextUtilities()}
            ${commonStyles.getModalDialogCSS()}
            ${commonStyles.getRadioAndCheckboxCss()}
            ${commonStyles.getTabulatorStyles()}
            ${fileHandlingStyles.getFileHandlingCss()}
            .breadcrumb-folder {
                padding-right: 5px;
                color: var(--dbp-muted);
                font-size: 1.4em;
                padding-top: 7px;
            }

            .breadcrumb.special a {
                overflow: visible;
            }

            .breadcrumb-menu {
                display: inline;
            }

            .breadcrumb {
                border-bottom: var(--dbp-border);
            }

            .breadcrumb:last-child,
            .breadcrumb:first-child {
                border-bottom: none;
            }

            .breadcrumb a {
                display: inline-block;
                height: 33px;
                vertical-align: middle;
                line-height: 33px;
            }

            span.first {
                margin-left: -6px;
            }

            a.home-link {
                padding-left: 6px;
                padding-right: 6px;
                margin-left: -6px;
            }

            .extended-menu-link {
                padding: 7px;
            }

            .extended-breadcrumb-menu li a {
                max-width: none;
                display: inline;
            }

            .nextcloud-nav {
                position: relative;
                width: 100%;
                display: flex;
                justify-content: space-between;
            }

            .nextcloud-nav p {
                align-self: center;
            }

            .nextcloud-nav h2 {
                padding-top: 10px;
            }

            .nextcloud-nav a {
                white-space: nowrap;
                overflow: hidden;
                text-overflow: ellipsis;
                max-width: 130px;
            }

            .nextcloud-nav a.home-link {
                font-size: 1.4em;
            }

            .nextcloud-header.hidden {
                display: none !important;
            }

            .nextcloud-header {
                padding-bottom: 7px;
                width: 100%;
            }

            .nextcloud-header div button {
                justify-self: start;
            }

            .extended-breadcrumb-menu li {
                padding: 7px;
                padding-right: 46px;
                overflow: hidden;
            }

            .extended-breadcrumb-menu li:hover {
                background-color: var(--dbp-hover-background-color);
            }

            .extended-breadcrumb-menu li.active {
                background-color: var(--dbp-content-surface);
            }

            .extended-breadcrumb-menu li:hover > a {
                color: var(--dbp-hover-color, var(--dbp-content));
            }

            .extended-breadcrumb-menu li.active > a {
                color: var(--dbp-on-content-surface);
            }

            .extended-breadcrumb-menu a.inactive {
                color: var(--dbp-muted);
                pointer-events: none;
                cursor: default;
            }

            .extended-breadcrumb-menu {
                list-style: none;
                border: var(--dbp-border);
                position: absolute;
                background-color: var(--dbp-background);
                z-index: 1000;
            }

            input[type='text']#tf-new-folder:focus {
                border: none;
                background: transparent;
                height: 100%;
            }

            input[type='text']#tf-new-folder:focus-visible {
                outline: none;
                box-shadow: none;
            }

            input[type='text']#tf-new-folder::placeholder {
                color: #333;
                font-weight: 300;
            }

            #tf-new-folder::-webkit-input-placeholder {
                color: #333;
                font-weight: 300;
            }

            #tf-new-folder:-moz-placeholder {
                color: #333;
                font-weight: 300;
            }

            #tf-new-folder::-moz-placeholder {
                color: #333;
                font-weight: 300;
            }

            #tf-new-folder::-ms-input-placeholder {
                color: #333;
                font-weight: 300;
            }

            input[type='text']#tf-new-folder {
                border: 0px;
                background: transparent;
                width: 100%;
                height: 100%;
                margin-left: -8px;
                color: white;
            }

            input[type='text']#tf-new-folder.smaller {
                width: calc(100% - 42px);
            }

            .visible {
                display: unset;
            }

            .block {
                margin-bottom: 10px;
            }

            .error {
                background-color: var(--dbp-background);
                color: var(--dbp-danger);
            }

            .filter-options-wrapper {
                padding-right: 0px;
                padding-top: 10px;
                padding-bottom: 10px;
                padding-left: 4px;
            }

            .extended-menu li {
                padding: 7px;
                padding-right: 46px;
            }

            .extended-menu a.inactive {
                color: var(--dbp-muted);
                pointer-events: none;
                cursor: default;
            }

            .extended-menu a {
                padding: 8px;
            }

            .extended-menu {
                list-style: none;
                border: var(--dbp-border);
                position: absolute;
                background-color: var(--dbp-background);
                z-index: 1000;
                right: 0px;
                border-radius: var(--dbp-border-radius);
            }

            .extended-menu li:hover {
                background-color: var(--dbp-hover-background-color);
            }

            .extended-menu li.active {
                background-color: var(--dbp-content-surface);
            }

            .extended-menu li:hover > a {
                color: var(--dbp-hover-color, var(--dbp-content));
            }

            .extended-menu li.active > a {
                color: var(--dbp-on-content-surface);
            }

            .extended-menu li.inactive:hover {
                background-color: var(--dbp-background);
            }

            .extended-menu li.inactive > a {
                color: var(--dbp-muted);
                pointer-events: none;
                cursor: default;
            }

            .nextcloud-intro {
                text-align: center;
            }

            .nextcloud-logo {
                width: 80px;
                height: 95px;
                justify-self: end;
                transition: all 0.5s ease;
                margin: auto;
            }

            .nextcloud-logo-image {
                height: 100%;
                width: 100%;
                background-image: var(
                        --dbp-override-image-nextcloud,
                        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M69.3 86.1l-46.1 0C11 85.9 1.1 75.9 1.1 63.7c0-11.8 9.1-21.4 20.6-22.4 0.5-15.2 13-27.4 28.3-27.4 3.4 0 6.6 0.5 9.2 1.6 6.2 2.1 11.4 6.4 14.8 12 6.5 1 12.7 4.3 16.9 9.1 5 5.5 7.8 12.6 7.8 19.9C98.8 72.8 85.6 86.1 69.3 86.1zM23.6 80.6h45.7c13.3 0 24-10.8 24-24 0-6-2.3-11.8-6.4-16.2 -3.7-4.2-9.1-6.9-14.9-7.5l-1.4-0.2L70 31.4c-2.8-5.1-7.2-8.9-12.6-10.7l-0.1 0c-2-0.8-4.5-1.2-7.2-1.2 -12.6 0-22.9 10.3-22.9 22.9v4.5h-3.6c-9.3 0-17 7.6-17 17C6.6 73 14.3 80.6 23.6 80.6z'/%3E%3C/svg%3E")
                );
                background-repeat: no-repeat;
                background-position: center;
            }

            .nextcloud-logo-sm {
                width: 40px;
                justify-self: inherit;
                margin-right: 70px;
                display: none;
            }

            .m-inherit {
                margin: inherit;
            }

            .wrapper {
                width: 100%;
                height: 100%;
                display: flex;
                flex-direction: column;
                justify-content: center;
                position: relative;
            }

            .select-button {
                justify-self: end;
            }

            .nextcloud-content {
                width: 100%;
                height: 100%;
                overflow-y: auto;
                -webkit-overflow-scrolling: touch;
            }

            .nextcloud-footer {
                background-color: var(--dbp-background);
                width: 100%;
                padding-top: 10px;
            }

            .nextcloud-footer-grid {
                width: 100%;
                display: flex;
                align-items: center;
                flex-direction: row-reverse;
                justify-content: space-between;
            }

            .additional-menu {
                white-space: nowrap;
                height: 33px;
                margin-right: -11px;
            }

            #replace-modal-box {
                display: flex;
                flex-direction: column;
                justify-content: center;
                padding: 30px;
                max-height: 450px;
                min-height: 450px;
                min-width: 380px;
                max-width: 190px;
            }

            #replace-modal-box .modal-header {
                display: flex;
                justify-content: space-evenly;
                align-items: baseline;
            }

            #replace-modal-box .modal-header h2 {
                font-size: 1.2rem;
                padding-right: 5px;
            }

            #replace-modal-box .modal-content {
                display: flex;
                flex-direction: column;
                height: 100%;
                justify-content: space-evenly;
            }

            #replace-modal-box .radio-btn {
                margin-right: 5px;
            }

            #replace-modal-box .modal-content label {
                display: block;
                width: 100%;
                text-align: left;
            }

            #replace-modal-box #replace-filename {
                display: block;
                width: 100%;
                margin-top: 8px;
            }

            #replace-modal-box input[type='text']:disabled {
                color: var(--dbp-muted);
            }

            #replace-modal-box .modal-content div {
                display: flex;
            }

            #replace-modal-box .modal-footer {
                padding-top: 15px;
            }

            #replace-modal-box .modal-footer .modal-footer-btn {
                display: flex;
                justify-content: space-between;
                padding-bottom: 15px;
            }

            input:disabled + label {
                color: var(--dbp-muted);
            }

            .inline-block {
                display: inline-block;
            }

            .inline-block {
                position: absolute;
                right: 0px;
                z-index: 1;
                background-color: var(--dbp-background);
                bottom: -45px;
            }

            .addRowAnimation {
                color: var(--dbp-content);
                animation: added 0.4s ease;
            }

            #abortButton {
                background-color: var(--dbp-background);
                color: var(--dbp-danger);
            }

            #abortButton:hover {
                color: var(--dbp-on-content-surface);
            }

            .menu-buttons {
                display: flex;
                gap: 1em;
            }

            @keyframes added {
                0% {
                    background-color: var(--dbp-background);
                }
                50% {
                    background-color: var(--dbp-success-surface);
                }
                100% {
                    background-color: var(--dbp-background);
                }
            }

            .spinner {
                font-size: 0.7em;
            }

            .nextcloud-picker-icon-disabled {
                opacity: 0.4;
            }

            .button.button,
            .button,
            button.dt-button {
                background-color: var(--dbp-background);
            }

            #new-folder {
                padding-right: 50px;
            }


            #replace-modal-box .modal-header {
                padding: 0px;
            }

            #replace-modal-content {
                padding: 0px;
                align-items: baseline;
            }

            #replace-modal-box .modal-header h2 {
                text-align: left;
            }

            #replace-modal .checkmark {
                height: 20px;
                width: 20px;
                left: 1px;
                top: 0px;
            }

            .checkmark {
                height: 20px;
                width: 20px;
                left: 11px;
                top: 4px;
            }

            .table-wrapper {
                max-width: 100%;
                width: 100%;
            }

            .button-container .checkmark::after {
                left: 6px;
                top: 1px;
                width: 5px;
                height: 11px;
            }

            .select-all-icon {
                height: 30px;
            }

            .remember-container {
                display: inline-block;
                line-height: 28px;
                padding-left: 34px;
            }

            .remember-container .checkmark {
                left: 7px;
            }

            .more-menu {
                height: 22.4px;
                width: 19px;
                margin-top: 4px;
            }

            #new-folder-modal-box {
                display: flex;
                flex-direction: column;
                justify-content: space-between;
                padding: 15px 20px 20px 20px;
                max-height: 190px;
                min-height: 190px;
                min-width: 320px;
                max-width: 400px;
            }

            #new-folder-modal-box header.modal-header {
                padding: 0px;
                display: flex;
                justify-content: space-between;
            }

            #new-folder-modal-box footer.modal-footer .modal-footer-btn {
                padding: 0px;
                display: flex;
                justify-content: space-between;
            }

            #new-folder-modal-content {
                display: block;
                padding-left: 0px;
                padding-right: 0px;
                overflow: unset;
            }

            #new-folder-modal-content div .input {
                width: 100%;
            }

            #new-folder-modal-content .nf-label {
                padding-bottom: 2px;
            }

            @media only screen and (orientation: portrait) and (max-width: 768px) {

                .nextcloud-header {
                    padding-bottom: 0px;
                    grid-area: header-l;
                    margin-bottom: 0px;
                }

                .nextcloud-nav h2 > a {
                    font-size: 1.3rem;
                }

                .nextcloud-nav h2 {
                    padding-top: 8px;
                }

                .nextcloud-nav a {
                    font-size: 1rem;
                    /** max-width: max-content; **/
                }

                .nextcloud-nav .home-link {
                    font-size: 1.2rem;
                }

                .nextcloud-logo-sm {
                    display: none;
                }

                .nextcloud-logo {
                    margin: 0 auto;
                }

                .nextcloud-content,
                .nextcloud-intro {
                    grid-area: content;
                    height: 100%;
                    justify-content: center;
                }

                .nextcloud-intro {
                    text-align: center;
                    display: flex;
                    flex-direction: column;
                }

                .nextcloud-footer {
                    bottom: 0px;
                    width: 100%;
                    left: 0px;
                }

                .nextcloud-footer-grid {
                    display: flex;
                    justify-content: center;
                    flex-direction: column-reverse;
                }

                .breadcrumb-arrow {
                    font-size: 1.6em;
                    vertical-align: middle;
                    padding-bottom: 3px;
                    padding-left: 2px;
                    padding-right: 2px;
                }

                .breadcrumb .extended-breadcrumb-menu a {
                    display: inherit;
                }

                .extended-breadcrumb-link {
                    margin-top: -4px;
                    font-size: 1.2em !important; /**TODO for demo purpose only */
                    font-weight: 400;
                }

                .extended-menu {
                    top: 0px;
                }

                .additional-menu {
                    position: inherit;
                    right: 0px;
                    margin-right: -12px;
                }

                .additional-menu button {
                    float: right;
                }

                .inline-block {
                    width: inherit;
                    position: absolute;
                    right: 52px;
                    z-index: 1;
                    background-color: var(--dbp-background);
                    bottom: 0px;
                }

                .add-folder-button {
                    right: 0px;
                    position: absolute;
                }

                .button-wrapper {
                    justify-self: start;
                }

                .wrapper {
                    display: flex;
                    justify-content: space-between;
                }

                .mobile-hidden {
                    display: none;
                }

                .info-box {
                    position: relative;
                }

                .select-button {
                    margin: 0px;
                }

                #new-folder {
                    width: 100%;
                }

                #replace-modal-box {
                    min-width: 100%;
                    max-width: 100%;
                }

                .hidden {
                    display: none;
                }

                .select-all-icon {
                    height: 32px;
                }
            }
        `;
    }

    render() {
        const i18n = this._i18n;
        const tabulatorCss = commonUtils.getAssetURL(
            pkgName,
            'tabulator-tables/css/tabulator.min.css'
        );

        return html`
            <div class="wrapper">
                <link rel="stylesheet" href="${tabulatorCss}"/>
                <div class="nextcloud-intro ${classMap({hidden: this.isPickerActive})}">
                    <div
                            class="nextcloud-logo ${classMap({
                                'nextcloud-logo-sm': this.isPickerActive,
                            })}">
                        <div class="nextcloud-logo-image"></div>
                    </div>
                    <div class="block text-center ${classMap({hidden: this.isPickerActive})}">
                        <h2 class="m-inherit">${this.nextcloudName}</h2>
                        <p class="m-inherit">
                            ${i18n.t('nextcloud-file-picker.init-text-1', {
                                name: this.nextcloudName,
                            })}
                            <br/>
                            ${i18n.t('nextcloud-file-picker.init-text-2')}
                            <br/>
                            <br/>
                        </p>
                    </div>
                    <div class="block ${classMap({hidden: this.isPickerActive})}">
                        <button
                                class="button  is-primary"
                                title="${i18n.t('nextcloud-file-picker.open-nextcloud-file-picker', {
                                    name: this.nextcloudName,
                                })}"
                                @click="${async () => {
                                    this.openFilePicker();
                                }}">
                            ${i18n.t('nextcloud-file-picker.connect-nextcloud', {
                                name: this.nextcloudName,
                            })}
                        </button>
                    </div>
                    <div
                            class="block text-center m-inherit ${classMap({
                                hidden: !this.storeSession || !this.isLoggedIn(),
                            })}">
                        <label class="button-container remember-container">
                            ${i18n.t('nextcloud-file-picker.remember-me', {
                                name: this.nextcloudName,
                            })}
                            <input type="checkbox" id="remember-checkbox" name="remember"/>
                            <span class="checkmark"></span>
                        </label>
                    </div>
                    <div
                            class="block text-center m-inherit ${classMap({
                                hidden: this.isPickerActive,
                            })}">
                        <p class="m-inherit">
                            <br/>
                            ${i18n.t('nextcloud-file-picker.auth-info')}
                            <slot name="auth-info">
                                <br/>
                                ${this.authInfo}
                            </slot>
                        </p>
                    </div>
                </div>
                <div class="nextcloud-header ${classMap({hidden: !this.isPickerActive})}">
                    <div class="nextcloud-nav">
                        <p>${this.getBreadcrumb()}</p>

                        <div class="menu-buttons">
                            <div class="add-folder ${classMap({hidden: this.storeSession})}">
                                <div class="inline-block">
                                    <div id="new-folder-wrapper" class="hidden">
                                        <input type="text"
                                               placeholder="${i18n.t('nextcloud-file-picker.new-folder-placeholder')}"
                                               name="new-folder" class="input" id="new-folder"/>
                                        <button class="button add-folder-button"
                                                title="${i18n.t('nextcloud-file-picker.add-folder')}"
                                                @click="${() => {
                                                    this.addFolder();
                                                }}">
                                            <dbp-icon name="checkmark-circle" class="nextcloud-add-folder"></dbp-icon>
                                        </button>
                                    </div>
                                </div>
                            </div>
                            <button class="button ${classMap({hidden: this.storeSession})}"
                                    title="${i18n.t('nextcloud-file-picker.add-folder-open')}"
                                    @click="${() => {
                                        this.openAddFolderDialogue();
                                    }}">
                                <dbp-icon name="plus" class="nextcloud-add-folder" id="add-folder-button"></dbp-icon>
                            </button>
                        </div>


                        <div class="additional-menu ${classMap({hidden: !this.storeSession})}">
                            <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>
                            </a>
                            <ul class="extended-menu hidden">
                                <li
                                        class="${classMap({active: this.isInFavorites})}"
                                        id="favorites-item">
                                    <a class="" @click="${this.loadFavorites}">
                                        ${i18n.t('nextcloud-file-picker.favorites-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({
                                    inactive:
                                            this.isInRecent ||
                                            this.isInFavorites ||
                                            this.isInFilteredRecent ||
                                            this.disableRowClick,
                                })}">
                                    <a class=""
                                       @click="${() => {
                                           this.addOpenFolderTableEntry();
                                       }}">
                                        ${i18n.t('nextcloud-file-picker.add-folder')}
                                    </a>
                                </li>
                                <li
                                        class="${classMap({hidden: !this.storeSession})}"
                                        title="${i18n.t('nextcloud-file-picker.log-out')}">
                                    <a
                                            class=""
                                            @click="${() => {
                                                this.logOut();
                                                this.hideAdditionalMenu();
                                            }}">
                                        ${i18n.t('nextcloud-file-picker.log-out')}
                                    </a>
                                </li>
                            </ul>
                        </div>
                    </div>
                </div>
                <div class="nextcloud-content ${classMap({hidden: !this.isPickerActive})}">
                    <div class="table-wrapper">
                        <table id="directory-content-table" class="force-no-select"></table>
                    </div>
                </div>

                <div class="nextcloud-footer ${classMap({hidden: !this.isPickerActive})}">
                    <div class="nextcloud-footer-grid">
                        <button
                                id="download-button"
                                class="button select-button is-primary ${classMap({
                                    hidden:
                                            !this.directoriesOnly ||
                                            (this.directoriesOnly && this.abortUploadButton && this.forAll),
                                })}"
                                @click="${() => {
                                    this.sendDirectory(this.tabulatorTable.getSelectedData());
                                }}"
                                ?disabled="${this.selectBtnDisabled}">
                            <dbp-icon class="nav-icon" name="cloud-upload"></dbp-icon>
                            ${this.folderIsSelected}
                        </button>
                        <button
                                class="button select-button is-primary ${classMap({
                                    hidden: this.directoriesOnly,
                                })}"
                                @click="${() => {
                                    this.downloadFiles(this.tabulatorTable.getSelectedData());
                                }}"
                                ?disabled="${this.selectBtnDisabled}">
                            ${this.tabulatorTable &&
                            this.tabulatorTable
                                    .getSelectedRows()
                                    .filter(
                                            (row) =>
                                                    row.getData().type != 'directory' &&
                                                    this.checkFileType(row.getData(), this.allowedMimeTypes)
                                    ).length === 0
                                    ? i18n.t('nextcloud-file-picker.select-files')
                                    : i18n.t('nextcloud-file-picker.select-files-btn', {
                                        count: this.tabulatorTable
                                                ? this.tabulatorTable.getSelectedRows().length
                                                : 0,
                                    })}
                        </button>
                        <button
                                id="abortButton"
                                class="button select-button hidden ${classMap({
                                    visible:
                                            this.directoriesOnly && this.forAll && this.abortUploadButton,
                                })}"
                                title="${i18n.t('nextcloud-file-picker.abort')}"
                                @click="${() => {
                                    this.abortUpload = true;
                                }}">
                            ${i18n.t('nextcloud-file-picker.abort')}
                        </button>

                        <div class="block info-box ${classMap({hidden: this.statusText === ''})}">
                            <dbp-mini-spinner
                                    class="spinner ${classMap({
                                        hidden: this.loading === false,
                                    })}"></dbp-mini-spinner>
                            <span>${this.statusText}</span>
                        </div>
                    </div>
                </div>
            </div>

            <div class="modal micromodal-slide" id="replace-modal" aria-hidden="true">
                <div class="modal-overlay" tabindex="-2" data-micromodal-close>
                    <div
                            class="modal-container"
                            id="replace-modal-box"
                            role="dialog"
                            aria-modal="true"
                            aria-labelledby="replace-modal-title">
                        <header class="modal-header">
                            <button
                                    title="${i18n.t('file-sink.modal-close')}"
                                    class="modal-close"
                                    aria-label="Close modal"
                                    @click="${() => {
                                        this.closeDialog();
                                    }}">
                                <dbp-icon
                                        title="${i18n.t('file-sink.modal-close')}"
                                        name="close"
                                        class="close-icon"></dbp-icon>
                            </button>
                            <h2 id="replace-modal-title">
                                ${i18n.t('nextcloud-file-picker.replace-title-1')}
                                <span style="word-break: break-all;">${this.replaceFilename}</span>
                                ${i18n.t('nextcloud-file-picker.replace-title-2')}.
                            </h2>
                        </header>
                        <main class="modal-content" id="replace-modal-content">
                            <h3>${i18n.t('nextcloud-file-picker.replace-text')}?</h3>
                            <div>
                                <label class="button-container">
                                    <span>
                                        ${i18n.t('nextcloud-file-picker.replace-new_name')}:
                                    </span>
                                    <input
                                            type="radio"
                                            id="replace-new-name"
                                            class="radio-btn"
                                            name="replacement"
                                            value="new-name"
                                            checked
                                            @click="${() => {
                                                this.setInputFieldVisibility();
                                            }}"/>
                                    <span class="radiobutton"></span>
                                    <input
                                            type="text"
                                            id="replace-filename"
                                            class="input"
                                            name="replace-filename"
                                            value=""
                                            onClick="this.select();"/>
                                </label>
                            </div>

                            <div>
                                <label class="button-container">
                                    <span>${i18n.t('nextcloud-file-picker.replace-replace')}</span>
                                    <input
                                            type="radio"
                                            id="replace-replace"
                                            name="replacement"
                                            value="replace"
                                            @click="${() => {
                                                this.setInputFieldVisibility();
                                            }}"/>
                                    <span class="radiobutton"></span>
                                </label>
                            </div>
                            <div>
                                <label class="button-container">
                                    <span>${i18n.t('nextcloud-file-picker.replace-skip')}</span>
                                    <input
                                            type="radio"
                                            class="radio-btn"
                                            name="replacement"
                                            value="ignore"
                                            @click="${() => {
                                                this.setInputFieldVisibility();
                                            }}"/>
                                    <span class="radiobutton"></span>
                                </label>
                            </div>
                        </main>
                        <footer class="modal-footer">
                            <div class="modal-footer-btn">
                                <button
                                        class="button"
                                        data-micromodal-close
                                        aria-label="Close this dialog window"
                                        @click="${() => {
                                            this.cancelOverwrite();
                                        }}">
                                    ${this.getCancelText()}
                                </button>
                                <button
                                        class="button select-button is-primary"
                                        @click="${() => {
                                            this.uploadFileAfterConflict();
                                        }}">
                                    OK
                                </button>
                            </div>
                            <div>
                                <label class="button-container">
                                    ${i18n.t('nextcloud-file-picker.replace-mode-all')}
                                    <input
                                            type="checkbox"
                                            id="replace_mode_all"
                                            name="replace_mode_all"
                                            value="replace_mode_all"
                                            @click="${() => {
                                                this.setRepeatForAllConflicts();
                                            }}"/>
                                    <span class="checkmark"></span>
                                </label>
                            </div>
                        </footer>
                    </div>
                </div>
            </div>

            <div class="modal micromodal-slide" id="new-folder-modal" aria-hidden="true">
                <div class="modal-overlay" tabindex="-2" data-micromodal-close>
                    <div
                            class="modal-container"
                            id="new-folder-modal-box"
                            role="dialog"
                            aria-modal="true"
                            aria-labelledby="new-folder-modal-title">
                        <header class="modal-header">
                            <button
                                    title="${i18n.t('file-sink.modal-close')}"
                                    class="modal-close"
                                    aria-label="Close modal"
                                    @click="${() => {
                                        this.deleteNewFolderEntry();
                                    }}">
                                <dbp-icon
                                        title="${i18n.t('file-sink.modal-close')}"
                                        name="close"
                                        class="close-icon"></dbp-icon>
                            </button>
                            <h3 id="new-folder-modal-title">
                                ${i18n.t('nextcloud-file-picker.new-folder-dialog-title')}
                            </h3>
                        </header>
                        <main class="modal-content" id="new-folder-modal-content">
                            <div class="nf-label">
                                ${i18n.t('nextcloud-file-picker.new-folder-dialog-label')}
                            </div>
                            <div>
                                <input
                                        type="text"
                                        class="input"
                                        name="tf-new-folder-dialog"
                                        id="tf-new-folder-dialog"
                                        value="${i18n.t('nextcloud-file-picker.new-folder-dialog-default-name')}"
                                        @input="${() => {
                                            this._atChangeInput();
                                        }}"
                                />
                            </div>
                        </main>
                        <footer class="modal-footer">
                            <div class="modal-footer-btn">
                                <button
                                        class="button"
                                        data-micromodal-close
                                        aria-label="Close this dialog window"
                                        @click="${() => {
                                            this.deleteNewFolderEntry();
                                        }}">
                                    ${i18n.t('nextcloud-file-picker.new-folder-dialog-button-cancel')}
                                </button>
                                <button
                                        class="button select-button is-primary"
                                        id="new-folder-confirm-btn"
                                        @click="${() => {
                                            this.addNewFolder();
                                        }}">
                                    ${i18n.t('nextcloud-file-picker.new-folder-dialog-button-ok')}
                                </button>
                            </div>
                        </footer>
                    </div>
                </div>
            </div>
        `;
    }
}