photos/js/photos-src_mixins_AbortCont...

1 line
96 KiB
XML

{"version":3,"file":"photos-src_mixins_AbortControllerMixin_js-src_mixins_FilesSelectionMixin_js-src_components_File_vue--80ca54.js?v=1ca8427980aecd4d23dd","mappings":"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","sources":["webpack:///photos/src/mixins/AbortControllerMixin.js","webpack:///photos/src/mixins/FilesSelectionMixin.js","webpack:///photos/src/mixins/UserConfig.js","webpack:///photos/src/components/File.vue?vue&type=style&index=0&id=5fd18e86&prod&lang=scss&scoped=true","webpack:///photos/src/components/FilesListViewer.vue?vue&type=style&index=0&id=3ae373ae&prod&lang=scss&scoped=true","webpack:///photos/src/components/TiledLayout/TiledLayout.vue?vue&type=style&index=0&id=2d8cabaa&prod&scoped=true&lang=scss","webpack:///photos/src/components/TiledLayout/TiledRows.vue?vue&type=style&index=0&id=c1815a46&prod&lang=scss&scoped=true","webpack:///photos/src/components/VirtualScrolling.vue?vue&type=style&index=0&id=7d847354&prod&scoped=true&lang=scss","webpack://photos/./src/components/File.vue?6403","webpack:///photos/src/components/File.vue","webpack:///photos/src/components/File.vue?vue&type=script&lang=js","webpack://photos/./src/components/File.vue?15b6","webpack://photos/./src/components/File.vue?f552","webpack://photos/./src/components/FilesListViewer.vue?033a","webpack:///photos/src/services/TiledLayout.js","webpack:///photos/src/components/TiledLayout/TiledRows.vue","webpack://photos/./src/components/TiledLayout/TiledRows.vue?7152","webpack://photos/./src/components/TiledLayout/TiledRows.vue?b628","webpack:///photos/src/components/TiledLayout/TiledLayout.vue?vue&type=script&lang=js","webpack:///photos/src/components/TiledLayout/TiledLayout.vue","webpack://photos/./src/components/TiledLayout/TiledLayout.vue?8dc6","webpack://photos/./src/components/TiledLayout/TiledLayout.vue?5c93","webpack://photos/./src/components/TiledLayout/TiledLayout.vue?b933","webpack:///photos/src/services/fileFetcher.js","webpack://photos/./src/components/VirtualScrolling.vue?3e35","webpack:///photos/src/components/VirtualScrolling.vue","webpack:///photos/src/components/VirtualScrolling.vue?vue&type=script&lang=js","webpack://photos/./src/components/VirtualScrolling.vue?9613","webpack://photos/./src/components/VirtualScrolling.vue?6e3f","webpack:///photos/src/components/FilesListViewer.vue","webpack:///photos/src/components/FilesListViewer.vue?vue&type=script&lang=js","webpack://photos/./src/components/FilesListViewer.vue?f3fb","webpack://photos/./src/components/FilesListViewer.vue?5a4f"],"sourcesContent":["/**\n * @copyright Copyright (c) 2022 Louis Chemineau <louis@chmn.me>\n *\n * @author Louis Chemineau <louis@chmn.me>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\nexport default {\n\tname: 'AbortControllerMixin',\n\n\tdata() {\n\t\treturn {\n\t\t\tabortController: new AbortController(),\n\t\t}\n\t},\n\n\tbeforeDestroy() {\n\t\tthis.abortController.abort()\n\t},\n\n\tbeforeRouteLeave(from, to, next) {\n\t\tthis.abortController.abort()\n\t\tthis.abortController = new AbortController()\n\t\tnext()\n\t},\n}\n","/**\n * @copyright Copyright (c) 2019 Louis Chemineau <louis@chmn.me>\n *\n * @author Louis Chemineau <louis@chmn.me>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\nexport default {\n\tname: 'FilesSelectionMixin',\n\n\tdata() {\n\t\treturn {\n\t\t\t/** @type {Object<string, boolean>} */\n\t\t\tselection: {},\n\t\t}\n\t},\n\n\twatch: {\n\t\t$route() {\n\t\t\tthis.resetSelection()\n\t\t},\n\t},\n\n\tmethods: {\n\t\tonFileSelectToggle({ id, value }) {\n\t\t\tthis.$set(this.selection, id, value)\n\t\t},\n\n\t\t/**\n\t\t * @param {string[]} filesIds - The ids of the files to uncheck.\n\t\t */\n\t\tonUncheckFiles(filesIds) {\n\t\t\tfilesIds.forEach((/** @type {string} */ filesId) => this.$set(this.selection, filesId, false))\n\t\t},\n\n\t\tresetSelection() {\n\t\t\tthis.selection = {}\n\t\t},\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * @return {string[]}\n\t\t */\n\t\tselectedFileIds() {\n\t\t\treturn Object.keys(this.selection).filter(fileId => this.selection[fileId])\n\t\t},\n\t},\n}\n","/**\n * @copyright Copyright (c) 2020 John Molakvoæ <skjnldsv@protonmail.com>\n *\n * @author John Molakvoæ <skjnldsv@protonmail.com>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\nimport { emit, subscribe, unsubscribe } from '@nextcloud/event-bus'\nimport { generateUrl } from '@nextcloud/router'\nimport { loadState } from '@nextcloud/initial-state'\nimport axios from '@nextcloud/axios'\n\nconst eventName = 'photos:user-config-changed'\n\nexport default {\n\tdata() {\n\t\tconst croppedLayoutLocalStorage = localStorage.getItem('photos:croppedLayout')\n\n\t\treturn {\n\t\t\tcroppedLayout: croppedLayoutLocalStorage !== null\n\t\t\t\t? croppedLayoutLocalStorage === 'true'\n\t\t\t\t: loadState('photos', 'croppedLayout', 'false') === 'true',\n\t\t\tphotosLocation: loadState('photos', 'photosLocation', ''),\n\t\t}\n\t},\n\n\tcreated() {\n\t\tsubscribe(eventName, this.updateLocalSetting)\n\t},\n\n\tbeforeDestroy() {\n\t\tunsubscribe(eventName, this.updateLocalSetting)\n\t},\n\n\tmethods: {\n\t\tupdateLocalSetting({ setting, value }) {\n\t\t\tthis[setting] = value\n\t\t},\n\t\tupdateSetting(setting) {\n\t\t\tconst value = this[setting]\n\t\t\t// Long time save setting\n\t\t\taxios.put(generateUrl('apps/photos/api/v1/config/' + setting), {\n\t\t\t\tvalue: value.toString(),\n\t\t\t})\n\t\t\t// Current session save setting\n\t\t\tlocalStorage.setItem('photos:' + setting, value)\n\t\t\t// Visible elements update setting\n\t\t\temit(eventName, { setting, value })\n\t\t},\n\t},\n}\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".file-container[data-v-5fd18e86]{background:var(--color-primary-light);position:relative;height:100%;width:100%;border:2px solid var(--color-main-background);box-sizing:border-box}.file-container.selected[data-v-5fd18e86]::after,.file-container[data-v-5fd18e86]:focus-within::after{position:absolute;top:0;left:0;z-index:2;width:100%;height:100%;content:\\\"\\\";outline:var(--color-primary) solid 4px;outline-offset:-4px;pointer-events:none}.file-container .file[data-v-5fd18e86]{width:100%;height:100%;box-sizing:border-box;outline:none;display:flex}.file-container .file__images[data-v-5fd18e86]{display:contents}.file-container .file__images .video-icon[data-v-5fd18e86]{position:absolute;top:0px;right:0px;width:100%;height:100%;z-index:1;opacity:.8}.file-container .file__images .video-icon[data-v-5fd18e86] .material-design-icon__svg{fill:var(--color-main-background)}.file-container .file__images img[data-v-5fd18e86]{width:100%;height:100%;object-fit:cover;position:absolute;color:rgba(0,0,0,0)}.file-container .file__images .loading-overlay[data-v-5fd18e86]{position:absolute;height:100%;width:100%;display:flex;align-content:center;align-items:center;justify-content:center}.file-container .file__images .loading-overlay svg[data-v-5fd18e86]{width:70%;height:70%}.file-container .file__hidden-description[data-v-5fd18e86]{position:absolute;left:-10000px;top:-10000px;width:1px;height:1px;overflow:hidden}.file-container .file__hidden-description.show[data-v-5fd18e86]{position:initial;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;height:-webkit-fit-content;height:-moz-fit-content;height:fit-content}.file-container:hover .selection-checkbox[data-v-5fd18e86],.file-container.selected .selection-checkbox[data-v-5fd18e86],.file-container:focus-within .selection-checkbox[data-v-5fd18e86]{display:flex}.file-container:hover .favorite-state[data-v-5fd18e86],.file-container.selected .favorite-state[data-v-5fd18e86],.file-container:focus-within .favorite-state[data-v-5fd18e86]{display:none}.file-container .selection-checkbox[data-v-5fd18e86]{display:none;position:absolute;top:8px;right:min(22px,50% - 7px);z-index:1;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.file-container .selection-checkbox[data-v-5fd18e86] .checkbox-radio-switch__label{padding:10px;box-sizing:border-box}.file-container .selection-checkbox[data-v-5fd18e86] .checkbox-radio-switch__label::after{content:\\\"\\\";background:var(--color-primary-light);width:16px;height:16px;position:absolute;left:14px;z-index:-1}.file-container .selection-checkbox[data-v-5fd18e86] .checkbox-radio-switch__label .checkbox-radio-switch__icon{margin:0}.file-container .selection-checkbox .input-label[data-v-5fd18e86]{position:fixed;z-index:-1;top:-5000px;left:-5000px}.file-container .favorite-state[data-v-5fd18e86]{position:absolute;top:2px;right:min(2px,50% - 7px)}.file-container .favorite-state[data-v-5fd18e86] .material-design-icon__svg{fill:#fc0}.file-container .favorite-state[data-v-5fd18e86] .material-design-icon__svg path{stroke:var(--color-primary-light);stroke-width:1px}\", \"\",{\"version\":3,\"sources\":[\"webpack://./src/components/File.vue\"],\"names\":[],\"mappings\":\"AAEA,iCACC,qCAAA,CACA,iBAAA,CACA,WAAA,CACA,UAAA,CACA,6CAAA,CACA,qBAAA,CAIC,sGACC,iBAAA,CACA,KAAA,CACA,MAAA,CACA,SAAA,CACA,UAAA,CACA,WAAA,CACA,UAAA,CACA,sCAAA,CACA,mBAAA,CACA,mBAAA,CAIF,uCACC,UAAA,CACA,WAAA,CACA,qBAAA,CACA,YAAA,CACA,YAAA,CAEA,+CACC,gBAAA,CAEA,2DACC,iBAAA,CACA,OAAA,CACA,SAAA,CACA,UAAA,CACA,WAAA,CACA,SAAA,CACA,UAAA,CAEA,sFACC,iCAAA,CAIF,mDACC,UAAA,CACA,WAAA,CACA,gBAAA,CACA,iBAAA,CACA,mBAAA,CAGD,gEACC,iBAAA,CACA,WAAA,CACA,UAAA,CACA,YAAA,CACA,oBAAA,CACA,kBAAA,CACA,sBAAA,CAEA,oEACC,SAAA,CACA,UAAA,CAKH,2DACC,iBAAA,CACA,aAAA,CACA,YAAA,CACA,SAAA,CACA,UAAA,CACA,eAAA,CAEA,gEACC,gBAAA,CACA,yBAAA,CAAA,sBAAA,CAAA,iBAAA,CACA,0BAAA,CAAA,uBAAA,CAAA,kBAAA,CAOF,2LACC,YAAA,CAGD,+KACC,YAAA,CAIF,qDACC,YAAA,CACA,iBAAA,CACA,OAAA,CAEA,yBAAA,CACA,SAAA,CACA,yBAAA,CAAA,sBAAA,CAAA,iBAAA,CAGA,mFACC,YAAA,CACA,qBAAA,CAGA,0FACC,UAAA,CACA,qCAAA,CACA,UAAA,CACA,WAAA,CACA,iBAAA,CACA,SAAA,CACA,UAAA,CAGD,gHACC,QAAA,CAIF,kEACC,cAAA,CACA,UAAA,CACA,WAAA,CACA,YAAA,CAIF,iDACC,iBAAA,CACA,OAAA,CAEA,wBAAA,CAEA,4EACC,SAAA,CAEA,iFACC,iCAAA,CACA,gBAAA\",\"sourcesContent\":[\"$sizes: (\\\"400\\\": (\\\"count\\\": 3, \\\"marginTop\\\": 66, \\\"marginW\\\": 8), \\\"700\\\": (\\\"count\\\": 4, \\\"marginTop\\\": 66, \\\"marginW\\\": 8), \\\"1024\\\": (\\\"count\\\": 5, \\\"marginTop\\\": 66, \\\"marginW\\\": 44), \\\"1280\\\": (\\\"count\\\": 4, \\\"marginTop\\\": 66, \\\"marginW\\\": 44), \\\"1440\\\": (\\\"count\\\": 5, \\\"marginTop\\\": 88, \\\"marginW\\\": 66), \\\"1600\\\": (\\\"count\\\": 6, \\\"marginTop\\\": 88, \\\"marginW\\\": 66), \\\"2048\\\": (\\\"count\\\": 7, \\\"marginTop\\\": 88, \\\"marginW\\\": 66), \\\"2560\\\": (\\\"count\\\": 8, \\\"marginTop\\\": 88, \\\"marginW\\\": 88), \\\"3440\\\": (\\\"count\\\": 9, \\\"marginTop\\\": 88, \\\"marginW\\\": 88), \\\"max\\\": (\\\"count\\\": 10, \\\"marginTop\\\": 88, \\\"marginW\\\": 88));\\n\\n.file-container {\\n\\tbackground: var(--color-primary-light);\\n\\tposition: relative;\\n\\theight: 100%;\\n\\twidth: 100%;\\n\\tborder: 2px solid var(--color-main-background); // Use border so create a separation between images.\\n\\tbox-sizing: border-box;\\n\\n\\t// Selection border.\\n\\t&.selected, &:focus-within {\\n\\t\\t&::after {\\n\\t\\t\\tposition: absolute;\\n\\t\\t\\ttop: 0;\\n\\t\\t\\tleft: 0;\\n\\t\\t\\tz-index: 2;\\n\\t\\t\\twidth: 100%;\\n\\t\\t\\theight: 100%;\\n\\t\\t\\tcontent: '';\\n\\t\\t\\toutline: var(--color-primary) solid 4px;\\n\\t\\t\\toutline-offset: -4px;\\n\\t\\t\\tpointer-events: none;\\n\\t\\t}\\n\\t}\\n\\n\\t.file {\\n\\t\\twidth: 100%;\\n\\t\\theight: 100%;\\n\\t\\tbox-sizing: border-box;\\n\\t\\toutline: none; // Override global focus state.\\n\\t\\tdisplay: flex; // Fill parent size\\n\\n\\t\\t&__images {\\n\\t\\t\\tdisplay: contents;\\n\\n\\t\\t\\t.video-icon {\\n\\t\\t\\t\\tposition: absolute;\\n\\t\\t\\t\\ttop: 0px;\\n\\t\\t\\t\\tright: 0px;\\n\\t\\t\\t\\twidth: 100%;\\n\\t\\t\\t\\theight: 100%;\\n\\t\\t\\t\\tz-index: 1;\\n\\t\\t\\t\\topacity: 0.8;\\n\\n\\t\\t\\t\\t:deep(.material-design-icon__svg) {\\n\\t\\t\\t\\t\\tfill: var(--color-main-background);\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\n\\t\\t\\timg {\\n\\t\\t\\t\\twidth: 100%;\\n\\t\\t\\t\\theight: 100%;\\n\\t\\t\\t\\tobject-fit: cover;\\n\\t\\t\\t\\tposition: absolute;\\n\\t\\t\\t\\tcolor: transparent; /// Hide alt='' text when loading.\\n\\t\\t\\t}\\n\\n\\t\\t\\t.loading-overlay {\\n\\t\\t\\t\\tposition: absolute;\\n\\t\\t\\t\\theight: 100%;\\n\\t\\t\\t\\twidth: 100%;\\n\\t\\t\\t\\tdisplay: flex;\\n\\t\\t\\t\\talign-content: center;\\n\\t\\t\\t\\talign-items: center;\\n\\t\\t\\t\\tjustify-content: center;\\n\\n\\t\\t\\t\\tsvg {\\n\\t\\t\\t\\t\\twidth: 70%;\\n\\t\\t\\t\\t\\theight: 70%;\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\n\\t\\t&__hidden-description {\\n\\t\\t\\tposition: absolute;\\n\\t\\t\\tleft: -10000px;\\n\\t\\t\\ttop: -10000px;\\n\\t\\t\\twidth: 1px;\\n\\t\\t\\theight: 1px;\\n\\t\\t\\toverflow: hidden;\\n\\n\\t\\t\\t&.show {\\n\\t\\t\\t\\tposition: initial;\\n\\t\\t\\t\\twidth: fit-content;\\n\\t\\t\\t\\theight: fit-content;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\n\\t// Reveal checkbox on hover.\\n\\t&:hover, &.selected, &:focus-within {\\n\\t\\t.selection-checkbox {\\n\\t\\t\\tdisplay: flex;\\n\\t\\t}\\n\\n\\t\\t.favorite-state {\\n\\t\\t\\tdisplay: none;\\n\\t\\t}\\n\\t}\\n\\n\\t.selection-checkbox {\\n\\t\\tdisplay: none;\\n\\t\\tposition: absolute;\\n\\t\\ttop: 8px;\\n\\t\\t// Fancy calculation to render the checkbox in the middle of narrow images.\\n\\t\\tright: min(22px, calc(50% - 7px));\\n\\t\\tz-index: 1;\\n\\t\\twidth: fit-content;\\n\\n\\t\\t// Make the checkbox background round on hover.\\n\\t\\t:deep(.checkbox-radio-switch__label) {\\n\\t\\t\\tpadding: 10px;\\n\\t\\t\\tbox-sizing: border-box;\\n\\n\\t\\t\\t// Add a background to the checkbox so we do not see the image through it.\\n\\t\\t\\t&::after {\\n\\t\\t\\t\\tcontent: '';\\n\\t\\t\\t\\tbackground: var(--color-primary-light);\\n\\t\\t\\t\\twidth: 16px;\\n\\t\\t\\t\\theight: 16px;\\n\\t\\t\\t\\tposition: absolute;\\n\\t\\t\\t\\tleft: 14px;\\n\\t\\t\\t\\tz-index: -1;\\n\\t\\t\\t}\\n\\n\\t\\t\\t.checkbox-radio-switch__icon {\\n\\t\\t\\t\\tmargin: 0;\\n\\t\\t\\t}\\n\\t\\t}\\n\\n\\t\\t.input-label {\\n\\t\\t\\tposition: fixed;\\n\\t\\t\\tz-index: -1;\\n\\t\\t\\ttop: -5000px;\\n\\t\\t\\tleft: -5000px;\\n\\t\\t}\\n\\t}\\n\\n\\t.favorite-state {\\n\\t\\tposition: absolute;\\n\\t\\ttop: 2px;\\n\\t\\t// Fancy calculation to render the start in the middle of narrow images.\\n\\t\\tright: min(2px, calc(50% - 7px));\\n\\n\\t\\t:deep(.material-design-icon__svg) {\\n\\t\\t\\tfill: #FC0;\\n\\n\\t\\t\\tpath {\\n\\t\\t\\t\\tstroke: var(--color-primary-light);\\n\\t\\t\\t\\tstroke-width: 1px;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".files-list-viewer[data-v-3ae373ae]{height:100%;position:relative}.files-list-viewer__placeholder[data-v-3ae373ae]{background:var(--color-primary-light);width:100%;height:100%;border:2px solid var(--color-main-background)}.files-list-viewer .tiled-container[data-v-3ae373ae]{flex-basis:0}.files-list-viewer ul[data-v-3ae373ae]{display:flex;flex-wrap:wrap}.files-list-viewer ul li[data-v-3ae373ae]{flex-grow:1}.files-list-viewer__section-header[data-v-3ae373ae]{position:-webkit-sticky;position:sticky;top:0;z-index:3;background:var(--color-main-background)}.files-list-viewer__loader[data-v-3ae373ae]{margin:50px 0}\", \"\",{\"version\":3,\"sources\":[\"webpack://./src/components/FilesListViewer.vue\"],\"names\":[],\"mappings\":\"AAEA,oCACC,WAAA,CACA,iBAAA,CAEA,iDACC,qCAAA,CACA,UAAA,CACA,WAAA,CACA,6CAAA,CAGD,qDACC,YAAA,CAGD,uCACC,YAAA,CACA,cAAA,CAEA,0CACC,WAAA,CAIF,oDACC,uBAAA,CAAA,eAAA,CACA,KAAA,CACA,SAAA,CACA,uCAAA,CAGD,4CACC,aAAA\",\"sourcesContent\":[\"$sizes: (\\\"400\\\": (\\\"count\\\": 3, \\\"marginTop\\\": 66, \\\"marginW\\\": 8), \\\"700\\\": (\\\"count\\\": 4, \\\"marginTop\\\": 66, \\\"marginW\\\": 8), \\\"1024\\\": (\\\"count\\\": 5, \\\"marginTop\\\": 66, \\\"marginW\\\": 44), \\\"1280\\\": (\\\"count\\\": 4, \\\"marginTop\\\": 66, \\\"marginW\\\": 44), \\\"1440\\\": (\\\"count\\\": 5, \\\"marginTop\\\": 88, \\\"marginW\\\": 66), \\\"1600\\\": (\\\"count\\\": 6, \\\"marginTop\\\": 88, \\\"marginW\\\": 66), \\\"2048\\\": (\\\"count\\\": 7, \\\"marginTop\\\": 88, \\\"marginW\\\": 66), \\\"2560\\\": (\\\"count\\\": 8, \\\"marginTop\\\": 88, \\\"marginW\\\": 88), \\\"3440\\\": (\\\"count\\\": 9, \\\"marginTop\\\": 88, \\\"marginW\\\": 88), \\\"max\\\": (\\\"count\\\": 10, \\\"marginTop\\\": 88, \\\"marginW\\\": 88));\\n\\n.files-list-viewer {\\n\\theight: 100%;\\n\\tposition: relative;\\n\\n\\t&__placeholder {\\n\\t\\tbackground: var(--color-primary-light);\\n\\t\\twidth: 100%;\\n\\t\\theight: 100%;\\n\\t\\tborder: 2px solid var(--color-main-background); // Use border so create a separation between images.\\n\\t}\\n\\n\\t.tiled-container {\\n\\t\\tflex-basis: 0;\\n\\t}\\n\\n\\tul {\\n\\t\\tdisplay: flex;\\n\\t\\tflex-wrap: wrap;\\n\\n\\t\\tli {\\n\\t\\t\\tflex-grow: 1;\\n\\t\\t}\\n\\t}\\n\\n\\t&__section-header {\\n\\t\\tposition: sticky;\\n\\t\\ttop: 0;\\n\\t\\tz-index: 3;\\n\\t\\tbackground: var(--color-main-background);\\n\\t}\\n\\n\\t&__loader {\\n\\t\\tmargin: 50px 0;\\n\\t}\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".tiled-container[data-v-2d8cabaa]{height:100%}.tiled-container .tiled-row[data-v-2d8cabaa]{display:flex}\", \"\",{\"version\":3,\"sources\":[\"webpack://./src/components/TiledLayout/TiledLayout.vue\"],\"names\":[],\"mappings\":\"AAEA,kCACC,WAAA,CAEA,6CACC,YAAA\",\"sourcesContent\":[\"$sizes: (\\\"400\\\": (\\\"count\\\": 3, \\\"marginTop\\\": 66, \\\"marginW\\\": 8), \\\"700\\\": (\\\"count\\\": 4, \\\"marginTop\\\": 66, \\\"marginW\\\": 8), \\\"1024\\\": (\\\"count\\\": 5, \\\"marginTop\\\": 66, \\\"marginW\\\": 44), \\\"1280\\\": (\\\"count\\\": 4, \\\"marginTop\\\": 66, \\\"marginW\\\": 44), \\\"1440\\\": (\\\"count\\\": 5, \\\"marginTop\\\": 88, \\\"marginW\\\": 66), \\\"1600\\\": (\\\"count\\\": 6, \\\"marginTop\\\": 88, \\\"marginW\\\": 66), \\\"2048\\\": (\\\"count\\\": 7, \\\"marginTop\\\": 88, \\\"marginW\\\": 66), \\\"2560\\\": (\\\"count\\\": 8, \\\"marginTop\\\": 88, \\\"marginW\\\": 88), \\\"3440\\\": (\\\"count\\\": 9, \\\"marginTop\\\": 88, \\\"marginW\\\": 88), \\\"max\\\": (\\\"count\\\": 10, \\\"marginTop\\\": 88, \\\"marginW\\\": 88));\\n\\n.tiled-container {\\n\\theight: 100%;\\n\\n\\t.tiled-row {\\n\\t\\tdisplay: flex;\\n\\t}\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".tiled-row[data-v-c1815a46]{display:flex}\", \"\",{\"version\":3,\"sources\":[\"webpack://./src/components/TiledLayout/TiledRows.vue\"],\"names\":[],\"mappings\":\"AAEA,4BACC,YAAA\",\"sourcesContent\":[\"$sizes: (\\\"400\\\": (\\\"count\\\": 3, \\\"marginTop\\\": 66, \\\"marginW\\\": 8), \\\"700\\\": (\\\"count\\\": 4, \\\"marginTop\\\": 66, \\\"marginW\\\": 8), \\\"1024\\\": (\\\"count\\\": 5, \\\"marginTop\\\": 66, \\\"marginW\\\": 44), \\\"1280\\\": (\\\"count\\\": 4, \\\"marginTop\\\": 66, \\\"marginW\\\": 44), \\\"1440\\\": (\\\"count\\\": 5, \\\"marginTop\\\": 88, \\\"marginW\\\": 66), \\\"1600\\\": (\\\"count\\\": 6, \\\"marginTop\\\": 88, \\\"marginW\\\": 66), \\\"2048\\\": (\\\"count\\\": 7, \\\"marginTop\\\": 88, \\\"marginW\\\": 66), \\\"2560\\\": (\\\"count\\\": 8, \\\"marginTop\\\": 88, \\\"marginW\\\": 88), \\\"3440\\\": (\\\"count\\\": 9, \\\"marginTop\\\": 88, \\\"marginW\\\": 88), \\\"max\\\": (\\\"count\\\": 10, \\\"marginTop\\\": 88, \\\"marginW\\\": 88));\\n\\n.tiled-row {\\n\\tdisplay: flex;\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".vs-container[data-v-7d847354]{overflow-y:scroll;height:100%}.vs-rows-container[data-v-7d847354]{box-sizing:border-box}\", \"\",{\"version\":3,\"sources\":[\"webpack://./src/components/VirtualScrolling.vue\"],\"names\":[],\"mappings\":\"AAEA,+BACC,iBAAA,CACA,WAAA,CAGD,oCACC,qBAAA\",\"sourcesContent\":[\"$sizes: (\\\"400\\\": (\\\"count\\\": 3, \\\"marginTop\\\": 66, \\\"marginW\\\": 8), \\\"700\\\": (\\\"count\\\": 4, \\\"marginTop\\\": 66, \\\"marginW\\\": 8), \\\"1024\\\": (\\\"count\\\": 5, \\\"marginTop\\\": 66, \\\"marginW\\\": 44), \\\"1280\\\": (\\\"count\\\": 4, \\\"marginTop\\\": 66, \\\"marginW\\\": 44), \\\"1440\\\": (\\\"count\\\": 5, \\\"marginTop\\\": 88, \\\"marginW\\\": 66), \\\"1600\\\": (\\\"count\\\": 6, \\\"marginTop\\\": 88, \\\"marginW\\\": 66), \\\"2048\\\": (\\\"count\\\": 7, \\\"marginTop\\\": 88, \\\"marginW\\\": 66), \\\"2560\\\": (\\\"count\\\": 8, \\\"marginTop\\\": 88, \\\"marginW\\\": 88), \\\"3440\\\": (\\\"count\\\": 9, \\\"marginTop\\\": 88, \\\"marginW\\\": 88), \\\"max\\\": (\\\"count\\\": 10, \\\"marginTop\\\": 88, \\\"marginW\\\": 88));\\n\\n.vs-container {\\n\\toverflow-y: scroll;\\n\\theight: 100%;\\n}\\n\\n.vs-rows-container {\\n\\tbox-sizing: border-box;\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","var render = function render(){var _vm=this,_c=_vm._self._c;return _c('div',{staticClass:\"file-container\",class:{selected: _vm.selected},attrs:{\"data-test\":\"media\"}},[_c('a',{staticClass:\"file\",attrs:{\"href\":_vm.file.source,\"aria-label\":_vm.ariaLabel},on:{\"click\":function($event){$event.stopPropagation();$event.preventDefault();return _vm.emitClick.apply(null, arguments)}}},[_c('div',{staticClass:\"file__images\"},[(_vm.file.mime.includes('video'))?_c('VideoIcon',{staticClass:\"video-icon\",attrs:{\"size\":64}}):_vm._e(),_vm._v(\" \"),(_vm.visibility !== 'none' && _vm.canLoad && !_vm.errorNear && !_vm.loadedVisible)?_c('img',{key:`${_vm.file.basename}-near`,ref:\"imgNear\",attrs:{\"src\":_vm.srcNear,\"alt\":_vm.file.basename,\"aria-describedby\":_vm.ariaDescription},on:{\"load\":_vm.onLoadNear,\"error\":_vm.onErrorNear}}):_vm._e(),_vm._v(\" \"),((_vm.visibility === 'visible' || (_vm.loadedVisible && _vm.visibility === 'near')) && _vm.canLoad && !_vm.errorVisible)?_c('img',{key:`${_vm.file.basename}-visible`,ref:\"imgVisible\",attrs:{\"src\":_vm.srcVisible,\"alt\":_vm.file.basename,\"aria-describedby\":_vm.ariaDescription},on:{\"load\":_vm.onLoadVisible,\"error\":_vm.onErrorVisible}}):_vm._e()],1),_vm._v(\" \"),_c('p',{staticClass:\"file__hidden-description\",class:{show: _vm.errorNear && _vm.errorVisible},attrs:{\"id\":_vm.ariaDescription}},[_vm._v(_vm._s(_vm.file.basename))])]),_vm._v(\" \"),(_vm.allowSelection)?_c('NcCheckboxRadioSwitch',{staticClass:\"selection-checkbox\",attrs:{\"checked\":_vm.selected},on:{\"update:checked\":_vm.onToggle}},[_c('span',{staticClass:\"input-label\"},[_vm._v(_vm._s(_vm.t('photos', 'Select image {imageName}', {imageName: _vm.file.basename})))])]):_vm._e(),_vm._v(\" \"),(_vm.file.favorite === 1)?_c('Star',{staticClass:\"favorite-state\",attrs:{\"aria-label\":_vm.t('photos', 'The file is in the favorites')}}):_vm._e()],1)\n}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","<!--\n - @copyright Copyright (c) 2020 Corentin Mors\n -\n - @license AGPL-3.0-or-later\n -\n - @author Corentin Mors <medias@pixelswap.fr>\n -\n - This program is free software: you can redistribute it and/or modify\n - it under the terms of the GNU Affero General Public License as\n - published by the Free Software Foundation, either version 3 of the\n - License, or (at your option) any later version.\n -\n - This program is distributed in the hope that it will be useful,\n - but WITHOUT ANY WARRANTY; without even the implied warranty of\n - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n - GNU Affero General Public License for more details.\n -\n - You should have received a copy of the GNU Affero General Public License\n - along with this program. If not, see <http://www.gnu.org/licenses/>.\n -\n -->\n\n<template>\n\t<div class=\"file-container\"\n\t\tdata-test=\"media\"\n\t\t:class=\"{selected}\">\n\t\t<a class=\"file\"\n\t\t\t:href=\"file.source\"\n\t\t\t:aria-label=\"ariaLabel\"\n\t\t\t@click.stop.prevent=\"emitClick\">\n\n\t\t\t<!-- image and loading placeholder -->\n\t\t\t<div class=\"file__images\">\n\t\t\t\t<VideoIcon v-if=\"file.mime.includes('video')\" class=\"video-icon\" :size=\"64\" />\n\n\t\t\t\t<img v-if=\"visibility !== 'none' && canLoad && !errorNear && !loadedVisible\"\n\t\t\t\t\tref=\"imgNear\"\n\t\t\t\t\t:key=\"`${file.basename}-near`\"\n\t\t\t\t\t:src=\"srcNear\"\n\t\t\t\t\t:alt=\"file.basename\"\n\t\t\t\t\t:aria-describedby=\"ariaDescription\"\n\t\t\t\t\t@load=\"onLoadNear\"\n\t\t\t\t\t@error=\"onErrorNear\">\n\n\t\t\t\t<img v-if=\"(visibility === 'visible' || (loadedVisible && visibility === 'near')) && canLoad && !errorVisible\"\n\t\t\t\t\tref=\"imgVisible\"\n\t\t\t\t\t:key=\"`${file.basename}-visible`\"\n\t\t\t\t\t:src=\"srcVisible\"\n\t\t\t\t\t:alt=\"file.basename\"\n\t\t\t\t\t:aria-describedby=\"ariaDescription\"\n\t\t\t\t\t@load=\"onLoadVisible\"\n\t\t\t\t\t@error=\"onErrorVisible\">\n\t\t\t</div>\n\n\t\t\t<!-- image description -->\n\t\t\t<p :id=\"ariaDescription\" class=\"file__hidden-description\" :class=\"{show: errorNear && errorVisible}\">{{ file.basename }}</p>\n\t\t</a>\n\n\t\t<NcCheckboxRadioSwitch v-if=\"allowSelection\"\n\t\t\tclass=\"selection-checkbox\"\n\t\t\t:checked=\"selected\"\n\t\t\t@update:checked=\"onToggle\">\n\t\t\t<span class=\"input-label\">{{ t('photos', 'Select image {imageName}', {imageName: file.basename}) }}</span>\n\t\t</NcCheckboxRadioSwitch>\n\n\t\t<Star v-if=\"file.favorite === 1\" class=\"favorite-state\" :aria-label=\"t('photos', 'The file is in the favorites')\" />\n\t</div>\n</template>\n\n<script>\nimport Star from 'vue-material-design-icons/Star.vue'\nimport VideoIcon from 'vue-material-design-icons/Video.vue'\n\nimport { generateUrl } from '@nextcloud/router'\nimport { NcCheckboxRadioSwitch } from '@nextcloud/vue'\n\nimport Semaphore from '../utils/semaphoreWithPriority.js'\n\nexport default {\n\tname: 'File',\n\tcomponents: {\n\t\tNcCheckboxRadioSwitch,\n\t\tStar,\n\t\tVideoIcon,\n\t},\n\tinheritAttrs: false,\n\tprops: {\n\t\tfile: {\n\t\t\ttype: Object,\n\t\t\trequired: true,\n\t\t},\n\t\tselected: {\n\t\t\ttype: Boolean,\n\t\t\trequired: true,\n\t\t},\n\t\tallowSelection: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\t\tvisibility: {\n\t\t\ttype: String,\n\t\t\trequired: true,\n\t\t},\n\t\tsemaphore: {\n\t\t\ttype: Semaphore,\n\t\t\trequired: true,\n\t\t},\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\tloadedNear: false,\n\t\t\tloadedVisible: false,\n\t\t\terrorNear: false,\n\t\t\terrorVisible: false,\n\t\t\tcanLoad: false,\n\t\t\tsemaphoreSymbol: null,\n\t\t\tisDestroyed: false,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/** @return {string} */\n\t\tariaDescription() {\n\t\t\treturn `image-description-${this.file.fileid}`\n\t\t},\n\t\t/** @return {string} */\n\t\tariaLabel() {\n\t\t\treturn t('photos', 'Open the full size \"{name}\" image', { name: this.file.basename })\n\t\t},\n\t\t/** @return {boolean} */\n\t\tisImage() {\n\t\t\treturn this.file.mime.startsWith('image')\n\t\t},\n\t\t/** @return {string} */\n\t\tdecodedEtag() {\n\t\t\treturn this.file.etag.replace('&quot;', '').replace('&quot;', '')\n\t\t},\n\t\t/** @return {string} */\n\t\tsrcVisible() {\n\t\t\treturn this.getItemURL(512)\n\t\t},\n\t\t/** @return {string} */\n\t\tsrcNear() {\n\t\t\treturn this.getItemURL(64)\n\t\t},\n\t},\n\n\tasync mounted() {\n\t\tthis.semaphoreSymbol = await this.semaphore.acquire(() => {\n\t\t\tswitch (this.visibility) {\n\t\t\tcase 'visible':\n\t\t\t\treturn 1\n\t\t\tcase 'near':\n\t\t\t\treturn 2\n\t\t\tdefault:\n\t\t\t\treturn 3\n\t\t\t}\n\t\t}, this.file.fileid)\n\n\t\tif (this.visibility === 'none' || this.isDestroyed) {\n\t\t\tthis.releaseSemaphore()\n\t\t\treturn\n\t\t}\n\n\t\tthis.canLoad = true\n\t},\n\n\tbeforeDestroy() {\n\t\tthis.isDestroyed = true\n\t\tthis.releaseSemaphore()\n\n\t\t// cancel any pending load\n\t\tif (this.$refs.imgNear !== undefined) {\n\t\t\tthis.$refs.imgNear.src = ''\n\t\t}\n\t\tif (this.$refs.srcVisible !== undefined) {\n\t\t\tthis.$refs.srcVisible.src = ''\n\t\t}\n\t},\n\n\tmethods: {\n\t\temitClick() {\n\t\t\tthis.$emit('click', this.file.fileid)\n\t\t},\n\n\t\t/** When the 'near' image is fully loaded by browser we release semaphore */\n\t\tonLoadNear() {\n\t\t\tthis.loadedNear = true\n\t\t\tthis.releaseSemaphore()\n\t\t},\n\n\t\t/** When the 'visible' image is fully loaded by browser we release semaphore */\n\t\tonLoadVisible() {\n\t\t\tthis.loadedVisible = true\n\t\t\tthis.releaseSemaphore()\n\t\t},\n\n\t\tonErrorNear() {\n\t\t\tthis.errorNear = true\n\t\t\tthis.releaseSemaphore()\n\t\t},\n\n\t\tonErrorVisible() {\n\t\t\tthis.errorVisible = true\n\t\t\tthis.releaseSemaphore()\n\t\t},\n\n\t\tonToggle(value) {\n\t\t\tthis.$emit('select-toggled', { id: this.file.fileid, value })\n\t\t},\n\n\t\tgetItemURL(size) {\n\t\t\tconst token = this.$route.params.token\n\t\t\tif (token) {\n\t\t\t\treturn generateUrl(`/apps/photos/api/v1/publicPreview/${this.file.fileid}?etag=${this.decodedEtag}&x=${size}&y=${size}&token=${token}`)\n\t\t\t} else {\n\t\t\t\treturn generateUrl(`/apps/photos/api/v1/preview/${this.file.fileid}?etag=${this.decodedEtag}&x=${size}&y=${size}`)\n\t\t\t}\n\t\t},\n\n\t\treleaseSemaphore() {\n\t\t\tif (this.semaphoreSymbol === null) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.semaphore.release(this.semaphoreSymbol)\n\t\t\tthis.semaphoreSymbol = null\n\t\t},\n\t},\n\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.file-container {\n\tbackground: var(--color-primary-light);\n\tposition: relative;\n\theight: 100%;\n\twidth: 100%;\n\tborder: 2px solid var(--color-main-background); // Use border so create a separation between images.\n\tbox-sizing: border-box;\n\n\t// Selection border.\n\t&.selected, &:focus-within {\n\t\t&::after {\n\t\t\tposition: absolute;\n\t\t\ttop: 0;\n\t\t\tleft: 0;\n\t\t\tz-index: 2;\n\t\t\twidth: 100%;\n\t\t\theight: 100%;\n\t\t\tcontent: '';\n\t\t\toutline: var(--color-primary) solid 4px;\n\t\t\toutline-offset: -4px;\n\t\t\tpointer-events: none;\n\t\t}\n\t}\n\n\t.file {\n\t\twidth: 100%;\n\t\theight: 100%;\n\t\tbox-sizing: border-box;\n\t\toutline: none; // Override global focus state.\n\t\tdisplay: flex; // Fill parent size\n\n\t\t&__images {\n\t\t\tdisplay: contents;\n\n\t\t\t.video-icon {\n\t\t\t\tposition: absolute;\n\t\t\t\ttop: 0px;\n\t\t\t\tright: 0px;\n\t\t\t\twidth: 100%;\n\t\t\t\theight: 100%;\n\t\t\t\tz-index: 1;\n\t\t\t\topacity: 0.8;\n\n\t\t\t\t:deep(.material-design-icon__svg) {\n\t\t\t\t\tfill: var(--color-main-background);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\timg {\n\t\t\t\twidth: 100%;\n\t\t\t\theight: 100%;\n\t\t\t\tobject-fit: cover;\n\t\t\t\tposition: absolute;\n\t\t\t\tcolor: transparent; /// Hide alt='' text when loading.\n\t\t\t}\n\n\t\t\t.loading-overlay {\n\t\t\t\tposition: absolute;\n\t\t\t\theight: 100%;\n\t\t\t\twidth: 100%;\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-content: center;\n\t\t\t\talign-items: center;\n\t\t\t\tjustify-content: center;\n\n\t\t\t\tsvg {\n\t\t\t\t\twidth: 70%;\n\t\t\t\t\theight: 70%;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t&__hidden-description {\n\t\t\tposition: absolute;\n\t\t\tleft: -10000px;\n\t\t\ttop: -10000px;\n\t\t\twidth: 1px;\n\t\t\theight: 1px;\n\t\t\toverflow: hidden;\n\n\t\t\t&.show {\n\t\t\t\tposition: initial;\n\t\t\t\twidth: fit-content;\n\t\t\t\theight: fit-content;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Reveal checkbox on hover.\n\t&:hover, &.selected, &:focus-within {\n\t\t.selection-checkbox {\n\t\t\tdisplay: flex;\n\t\t}\n\n\t\t.favorite-state {\n\t\t\tdisplay: none;\n\t\t}\n\t}\n\n\t.selection-checkbox {\n\t\tdisplay: none;\n\t\tposition: absolute;\n\t\ttop: 8px;\n\t\t// Fancy calculation to render the checkbox in the middle of narrow images.\n\t\tright: min(22px, calc(50% - 7px));\n\t\tz-index: 1;\n\t\twidth: fit-content;\n\n\t\t// Make the checkbox background round on hover.\n\t\t:deep(.checkbox-radio-switch__label) {\n\t\t\tpadding: 10px;\n\t\t\tbox-sizing: border-box;\n\n\t\t\t// Add a background to the checkbox so we do not see the image through it.\n\t\t\t&::after {\n\t\t\t\tcontent: '';\n\t\t\t\tbackground: var(--color-primary-light);\n\t\t\t\twidth: 16px;\n\t\t\t\theight: 16px;\n\t\t\t\tposition: absolute;\n\t\t\t\tleft: 14px;\n\t\t\t\tz-index: -1;\n\t\t\t}\n\n\t\t\t.checkbox-radio-switch__icon {\n\t\t\t\tmargin: 0;\n\t\t\t}\n\t\t}\n\n\t\t.input-label {\n\t\t\tposition: fixed;\n\t\t\tz-index: -1;\n\t\t\ttop: -5000px;\n\t\t\tleft: -5000px;\n\t\t}\n\t}\n\n\t.favorite-state {\n\t\tposition: absolute;\n\t\ttop: 2px;\n\t\t// Fancy calculation to render the start in the middle of narrow images.\n\t\tright: min(2px, calc(50% - 7px));\n\n\t\t:deep(.material-design-icon__svg) {\n\t\t\tfill: #FC0;\n\n\t\t\tpath {\n\t\t\t\tstroke: var(--color-primary-light);\n\t\t\t\tstroke-width: 1px;\n\t\t\t}\n\t\t}\n\t}\n}\n</style>\n","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./File.vue?vue&type=script&lang=js\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./File.vue?vue&type=script&lang=js\"","\n import API from \"!../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/postcss-loader/dist/cjs.js!../../node_modules/sass-loader/dist/cjs.js??clonedRuleSet-2.use[3]!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./File.vue?vue&type=style&index=0&id=5fd18e86&prod&lang=scss&scoped=true\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/postcss-loader/dist/cjs.js!../../node_modules/sass-loader/dist/cjs.js??clonedRuleSet-2.use[3]!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./File.vue?vue&type=style&index=0&id=5fd18e86&prod&lang=scss&scoped=true\";\n export default content && content.locals ? content.locals : undefined;\n","import { render, staticRenderFns } from \"./File.vue?vue&type=template&id=5fd18e86&scoped=true\"\nimport script from \"./File.vue?vue&type=script&lang=js\"\nexport * from \"./File.vue?vue&type=script&lang=js\"\nimport style0 from \"./File.vue?vue&type=style&index=0&id=5fd18e86&prod&lang=scss&scoped=true\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"5fd18e86\",\n null\n \n)\n\nexport default component.exports","var render = function render(){var _vm=this,_c=_vm._self._c;return _c('div',{staticClass:\"files-list-viewer\"},[(_vm.emptyMessage !== '' && _vm.items.length === 0 && !_vm.loading)?_c('NcEmptyContent',{key:\"emptycontent\",attrs:{\"title\":_vm.emptyMessage}},[_c('PackageVariant',{attrs:{\"slot\":\"icon\"},slot:\"icon\"})],1):_vm._e(),_vm._v(\" \"),_c('TiledLayout',{attrs:{\"base-height\":_vm.baseHeight,\"items\":_vm.items},scopedSlots:_vm._u([{key:\"default\",fn:function({rows}){return _c('VirtualScrolling',{attrs:{\"use-window\":_vm.useWindow,\"container-element\":_vm.containerElement,\"rows\":rows,\"scroll-to-key\":_vm.scrollToSection},on:{\"need-content\":_vm.needContent},scopedSlots:_vm._u([{key:\"default\",fn:function({renderedRows}){return _c('ul',{},[_vm._l((renderedRows),function(row){return _vm._l((row.items),function(item){return _c('li',{key:item.id,class:{'files-list-viewer__section-header': item.sectionHeader},style:({ 'flex-basis': item.ratio ? `${row.height * item.ratio - 1}px` : '100%', height: `${row.height}px`})},[(_vm.showPlaceholders)?_c('div',{staticClass:\"files-list-viewer__placeholder\"}):_vm._t(\"default\",null,{\"file\":item,\"visibility\":row.visibility})],2)})})],2)}}])},[_vm._v(\" \"),(_vm.loading && !_vm.showPlaceholders)?_c('NcLoadingIcon',{staticClass:\"files-list-viewer__loader\",attrs:{\"slot\":\"loader\"},slot:\"loader\"}):_vm._e()],1)}}])})],1)\n}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","/**\n * @copyright Copyright (c) 2022 Louis Chemineau <louis@chmn.me>\n *\n * @author Louis Chemineau <louis@chmn.me>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\n/**\n * @typedef {object} TiledItem\n * @property {string} id\n * @property {number} [width] Real width of the item.\n * @property {number} height Real height of the item.\n * @property {number} [ratio] The aspect ratio of the item.\n * @property {boolean} [sectionHeader] Whether this row is a section header.\n */\n\n/**\n * @typedef {object} TiledRow\n * @property {TiledItem[]} items -\n * @property {number} height -\n * @property {string} key -\n */\n\n/**\n * Split items in rows of equal width.\n * The last row will not be forced to match containerWidth.\n *\n * @param {TiledItem[]} items The list of item to split in row of equal width.\n * @param {number} containerWidth The width of a row.\n * @param {number} baseHeight The base height of the rows.\n * @return {TiledRow[]}\n */\nexport function splitItemsInRows(items, containerWidth, baseHeight = 200) {\n\tif (containerWidth === 0) {\n\t\treturn []\n\t}\n\n\tconst rows = []\n\tlet rowNumber = 0\n\tlet currentItem = 0\n\n\twhile (currentItem < items.length) {\n\t\t/** @type { TiledItem[] } */\n\t\tconst rowItems = []\n\n\t\t// Fill the row with new items as long as the width is less than containerWidth.\n\t\tdo {\n\t\t\t// @ts-ignore - We know that items.shift() is not undefined as we always check that items.length > 0.\n\t\t\trowItems.push(items[currentItem++])\n\t\t} while (\n\t\t\tcurrentItem < items.length\n\t\t\t&& !items[currentItem - 1].sectionHeader && !items[currentItem].sectionHeader\n\t\t\t&& computeRowWidth([...rowItems, items[currentItem]], baseHeight) <= containerWidth\n\t\t)\n\n\t\trows[rowNumber] = {\n\t\t\titems: rowItems,\n\t\t\theight: computeRowHeight(\n\t\t\t\trowItems,\n\t\t\t\tcontainerWidth,\n\t\t\t\titems.length === currentItem || items[currentItem].sectionHeader === true,\n\t\t\t\tbaseHeight\n\t\t\t),\n\t\t\t// Key to help vue to keep track of the row in VirtualScrolling.\n\t\t\tkey: rowItems.map(item => item.id).join('-'),\n\t\t}\n\n\t\trowNumber += 1\n\t}\n\n\treturn rows\n}\n\n/**\n *\n * @param {TiledItem[]} items The list of items in the row.\n * @param {number} baseHeight The base height of the rows.\n * @return {number} The width of the row\n */\nfunction computeRowWidth(items, baseHeight) {\n\treturn items\n\t\t.map(item => baseHeight * item.ratio)\n\t\t.reduce((sum, itemWidth) => sum + itemWidth)\n}\n\n/**\n * Compute the row height based on its items and on the container's width.\n *\n * Math time !\n * With Rn the aspect ratio of item n\n * Wn the width of item n\n * Hn the height of item n\n * Wc the width of the container\n * Hr the height of the row\n * For n items we want: Wc = W1 + W2 + ... + Wn\n * We know Rn = Wn / Hn\n * So Wn = Rn * Hn\n * So Wc = (R1 * H1) + (R2 * H2) + ... + (Rn * Hn)\n * But we also want Hr === H1 === H2 === ... === Hn\n * So Wc = (R1 * Hr) + (R2 * Hr) + ... + (Rn * Hr)\n * So Wc = Hr * (R1 + R2 + ... + Rn)\n * So Hr = Wc / (R1 + R2 + ... + Rn)\n *\n * @param {TiledItem[]} items The list of items in the row.\n * @param {number} containerWidth The width of the row.\n * @param {boolean} isLastRow Whether we are computing the height for the last row.\n * @param {number} baseHeight The base height of the rows.\n * @return {number} The height of the row\n */\nfunction computeRowHeight(items, containerWidth, isLastRow, baseHeight) {\n\t// Exception 1: there is only one item and its width it is a sectionHeader, meaning take the full width.\n\tif (items.length === 1 && items[0].sectionHeader) {\n\t\treturn items[0].height\n\t}\n\n\tconst sumOfItemsRatio = items\n\t\t.map(item => item.ratio)\n\t\t.reduce((sum, itemRatio) => sum + itemRatio\n\t\t)\n\n\tlet rowHeight = containerWidth / sumOfItemsRatio\n\n\t// Exception 2: there is only one item which is larger than containerWidth.\n\t// Limit its height so that itemWidth === containerWidth\n\tif (items.length === 1 && items[0].width > containerWidth) {\n\t\trowHeight = containerWidth / items[0].ratio\n\t}\n\n\t// Exception 3: we reached the last row.\n\t// Force the items width to match containerWidth, and limit their heigh to baseHeight + 20.\n\tif (isLastRow) {\n\t\trowHeight = Math.min(baseHeight + 20, rowHeight)\n\t}\n\n\treturn rowHeight\n}\n","var render = function render(_c,_vm){return _c('ul',_vm._l((_vm.props.rows),function(row){return _c('div',{key:row.key,staticClass:\"tiled-row\",style:({height: `${row.height}px`})},_vm._l((row.items),function(item){return _c('li',{key:item.id,style:({ width: item.ratio ? `${row.height * item.ratio}px` : '100%', height: `${row.height}px`})},[_vm._t(\"default\",null,{\"row\":row,\"item\":item})],2)}),0)}),0)\n}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","\n import API from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/postcss-loader/dist/cjs.js!../../../node_modules/sass-loader/dist/cjs.js??clonedRuleSet-2.use[3]!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./TiledRows.vue?vue&type=style&index=0&id=c1815a46&prod&lang=scss&scoped=true\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/postcss-loader/dist/cjs.js!../../../node_modules/sass-loader/dist/cjs.js??clonedRuleSet-2.use[3]!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./TiledRows.vue?vue&type=style&index=0&id=c1815a46&prod&lang=scss&scoped=true\";\n export default content && content.locals ? content.locals : undefined;\n","import { render, staticRenderFns } from \"./TiledRows.vue?vue&type=template&id=c1815a46&scoped=true&functional=true\"\nvar script = {}\nimport style0 from \"./TiledRows.vue?vue&type=style&index=0&id=c1815a46&prod&lang=scss&scoped=true\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n true,\n null,\n \"c1815a46\",\n null\n \n)\n\nexport default component.exports","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./TiledLayout.vue?vue&type=script&lang=js\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./TiledLayout.vue?vue&type=script&lang=js\"","<!--\n - @copyright Copyright (c) 2022 Louis Chemineau <louis@chmn.me>\n -\n - @author Louis Chemineau <louis@chmn.me>\n -\n - @license AGPL-3.0-or-later\n -\n - This program is free software: you can redistribute it and/or modify\n - it under the terms of the GNU Affero General Public License as\n - published by the Free Software Foundation, either version 3 of the\n - License, or (at your option) any later version.\n -\n - This program is distributed in the hope that it will be useful,\n - but WITHOUT ANY WARRANTY; without even the implied warranty of\n - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n - GNU Affero General Public License for more details.\n -\n - You should have received a copy of the GNU Affero General Public License\n - along with this program. If not, see <http://www.gnu.org/licenses/>.\n -\n -->\n<template>\n\t<div ref=\"tiledLayoutContainer\"\n\t\tclass=\"tiled-container\">\n\t\t<!-- Slot to allow changing the rows before passing them to TiledRows -->\n\t\t<!-- Useful for partially rendering rows like with VirtualScrolling -->\n\t\t<slot :rows=\"rows\">\n\t\t\t<!-- Default rendering -->\n\t\t\t<TiledRows :rows=\"rows\" />\n\t\t</slot>\n\t</div>\n</template>\n\n<script>\nimport logger from '../../services/logger.js'\nimport { splitItemsInRows } from '../../services/TiledLayout.js'\nimport TiledRows from './TiledRows.vue'\n\nexport default {\n\tname: 'TiledLayout',\n\n\tcomponents: {\n\t\tTiledRows,\n\t},\n\n\tprops: {\n\t\titems: {\n\t\t\ttype: Array,\n\t\t\trequired: true,\n\t\t},\n\t\tbaseHeight: {\n\t\t\ttype: Number,\n\t\t\tdefault: 200,\n\t\t},\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\tcontainerWidth: 0,\n\t\t\t/** @type {ResizeObserver} */\n\t\t\tresizeObserver: null,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/** @return {import('../services/TiledLayout.js').TiledRow[]} */\n\t\trows() {\n\t\t\tlogger.debug('[TiledLayout] Computing rows', { items: this.items })\n\n\t\t\treturn splitItemsInRows(this.items, this.containerWidth, this.baseHeight)\n\t\t},\n\t},\n\n\tmounted() {\n\t\tthis.resizeObserver = new ResizeObserver(entries => {\n\t\t\tfor (const entry of entries) {\n\t\t\t\tconst cr = entry.contentRect\n\t\t\t\tif (entry.target.classList.contains('tiled-container')) {\n\t\t\t\t\tthis.containerWidth = cr.width\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\n\t\tthis.resizeObserver.observe(this.$refs.tiledLayoutContainer)\n\t},\n\n\tbeforeDestroy() {\n\t\tthis.resizeObserver.disconnect()\n\t},\n}\n</script>\n\n<style scoped lang=\"scss\">\n.tiled-container {\n\theight: 100%;\n\n\t.tiled-row {\n\t\tdisplay: flex;\n\t}\n}\n</style>\n","\n import API from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/postcss-loader/dist/cjs.js!../../../node_modules/sass-loader/dist/cjs.js??clonedRuleSet-2.use[3]!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./TiledLayout.vue?vue&type=style&index=0&id=2d8cabaa&prod&scoped=true&lang=scss\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/postcss-loader/dist/cjs.js!../../../node_modules/sass-loader/dist/cjs.js??clonedRuleSet-2.use[3]!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./TiledLayout.vue?vue&type=style&index=0&id=2d8cabaa&prod&scoped=true&lang=scss\";\n export default content && content.locals ? content.locals : undefined;\n","import { render, staticRenderFns } from \"./TiledLayout.vue?vue&type=template&id=2d8cabaa&scoped=true\"\nimport script from \"./TiledLayout.vue?vue&type=script&lang=js\"\nexport * from \"./TiledLayout.vue?vue&type=script&lang=js\"\nimport style0 from \"./TiledLayout.vue?vue&type=style&index=0&id=2d8cabaa&prod&scoped=true&lang=scss\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"2d8cabaa\",\n null\n \n)\n\nexport default component.exports","var render = function render(){var _vm=this,_c=_vm._self._c;return _c('div',{ref:\"tiledLayoutContainer\",staticClass:\"tiled-container\"},[_vm._t(\"default\",function(){return [_c('TiledRows',{attrs:{\"rows\":_vm.rows}})]},{\"rows\":_vm.rows})],2)\n}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","/**\n * @copyright Copyright (c) 2023 Louis Chemineau <louis@chmn.me>\n *\n * @author Louis Chemineau <louis@chmn.me>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\nimport { genFileInfo } from '../utils/fileUtils.js'\nimport defaultClient from './DavClient.js'\n\n/**\n * @param {string[]} extraProps - Extra properties to add to the DAV request.\n * @return {string}\n */\nfunction getCollectionFilesDavRequest(extraProps = []) {\n\treturn `<?xml version=\"1.0\"?>\n\t\t\t<d:propfind xmlns:d=\"DAV:\"\n\t\t\t\txmlns:oc=\"http://owncloud.org/ns\"\n\t\t\t\txmlns:nc=\"http://nextcloud.org/ns\"\n\t\t\t\txmlns:ocs=\"http://open-collaboration-services.org/ns\">\n\t\t\t\t<d:prop>\n\t\t\t\t\t<d:getcontentlength />\n\t\t\t\t\t<d:getcontenttype />\n\t\t\t\t\t<d:getetag />\n\t\t\t\t\t<d:getlastmodified />\n\t\t\t\t\t<d:resourcetype />\n\t\t\t\t\t<nc:file-metadata-size />\n\t\t\t\t\t<nc:has-preview />\n\t\t\t\t\t<oc:favorite />\n\t\t\t\t\t<oc:fileid />\n\t\t\t\t\t<oc:permissions />\n\t\t\t\t\t${extraProps.join('')}\n\t\t\t\t</d:prop>\n\t\t\t</d:propfind>`\n}\n\n/**\n * @param {string} fileName - The full file's name\n * @param {import('webdav').StatOptions} options - Options to forward to the webdav client.\n * @return {Promise<object>}\n */\nexport async function fetchFile(fileName, options = {}) {\n\ttry {\n\t\tconst response = await defaultClient.stat(fileName, {\n\t\t\tdata: getCollectionFilesDavRequest(),\n\t\t\tdetails: true,\n\t\t\t...options,\n\t\t})\n\n\t\treturn genFileInfo(response.data)\n\t} catch (error) {\n\t\tif (error.code === 'ERR_CANCELED') {\n\t\t\treturn null\n\t\t}\n\n\t\tthrow error\n\t}\n}\n","var render = function render(){var _vm=this,_c=_vm._self._c;return (!_vm.useWindow && _vm.containerElement === null)?_c('div',{ref:\"container\",staticClass:\"vs-container\"},[_c('div',{ref:\"rowsContainer\",staticClass:\"vs-rows-container\",style:(_vm.rowsContainerStyle)},[_vm._t(\"default\",null,{\"renderedRows\":_vm.visibleRows}),_vm._v(\" \"),_vm._t(\"loader\")],2)]):_c('div',{ref:\"rowsContainer\",staticClass:\"vs-rows-container\",style:(_vm.rowsContainerStyle)},[_vm._t(\"default\",null,{\"renderedRows\":_vm.visibleRows}),_vm._v(\" \"),_vm._t(\"loader\")],2)\n}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","<!--\n - @copyright Copyright (c) 2022 Louis Chemineau <louis@chmn.me>\n -\n - @author Louis Chemineau <louis@chmn.me>\n -\n - @license AGPL-3.0-or-later\n -\n - This program is free software: you can redistribute it and/or modify\n - it under the terms of the GNU Affero General Public License as\n - published by the Free Software Foundation, either version 3 of the\n - License, or (at your option) any later version.\n -\n - This program is distributed in the hope that it will be useful,\n - but WITHOUT ANY WARRANTY; without even the implied warranty of\n - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n - GNU Affero General Public License for more details.\n -\n - You should have received a copy of the GNU Affero General Public License\n - along with this program. If not, see <http://www.gnu.org/licenses/>.\n -\n -->\n<template>\n\t<div v-if=\"!useWindow && containerElement === null\" ref=\"container\" class=\"vs-container\">\n\t\t<div ref=\"rowsContainer\"\n\t\t\tclass=\"vs-rows-container\"\n\t\t\t:style=\"rowsContainerStyle\">\n\t\t\t<slot :rendered-rows=\"visibleRows\" />\n\t\t\t<slot name=\"loader\" />\n\t\t</div>\n\t</div>\n\t<div v-else\n\t\tref=\"rowsContainer\"\n\t\tclass=\"vs-rows-container\"\n\t\t:style=\"rowsContainerStyle\">\n\t\t<slot :rendered-rows=\"visibleRows\" />\n\t\t<slot name=\"loader\" />\n\t</div>\n</template>\n\n<script>\nimport { debounce } from 'debounce'\n\nimport logger from '../services/logger.js'\n/**\n * @typedef {object} Row\n * @property {number} height - The height of the row.\n */\n\n/**\n * @typedef {Row} VisibleRow\n * @property {'none'|'near'|'visible'} visibility - The visibility state of the row\n * @property {boolean} shouldRender - Whether the row should be renderer in the DOM\n */\n\nexport default {\n\tname: 'VirtualScrolling',\n\n\tprops: {\n\t\trows: {\n\t\t\ttype: Array,\n\t\t\trequired: true,\n\t\t},\n\n\t\tcontainerElement: {\n\t\t\ttype: HTMLElement,\n\t\t\tdefault: null,\n\t\t},\n\n\t\tuseWindow: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\trenderWindowRatio: {\n\t\t\ttype: Number,\n\t\t\tdefault: 4,\n\t\t},\n\t\twillBeVisibleWindowRatio: {\n\t\t\ttype: Number,\n\t\t\tdefault: 4,\n\t\t},\n\t\tvisibleWindowRatio: {\n\t\t\ttype: Number,\n\t\t\t// A little bit more than the container's height to include items at its edges.\n\t\t\tdefault: 0,\n\t\t},\n\t\tbottomBufferRatio: {\n\t\t\ttype: Number,\n\t\t\tdefault: 5,\n\t\t},\n\t\tscrollToKey: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\tscrollPosition: 0,\n\t\t\tcontainerHeight: 0,\n\t\t\trowsContainerHeight: 0,\n\t\t\t/** @type {ResizeObserver} */\n\t\t\tresizeObserver: null,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * @return {VisibleRow[]}\n\t\t */\n\t\tvisibleRows() {\n\t\t\tlogger.debug('[VirtualScrolling] Computing visible rows', this.rows)\n\n\t\t\t// Optimisation: get those computed properties once to not go through vue's internal every time we need them.\n\t\t\tconst scrollPosition = this.scrollPosition\n\t\t\tconst containerHeight = this.containerHeight\n\n\t\t\t// Optimisation: different windows to hint the items how they should render themselves.\n\t\t\t// This will be forwarded with the visibility props.\n\t\t\tconst shouldRenderedWindow = containerHeight * this.renderWindowRatio\n\t\t\tconst willBeVisibleWindow = containerHeight * this.willBeVisibleWindowRatio\n\t\t\tconst visibleWindow = containerHeight * this.visibleWindowRatio\n\n\t\t\tlet currentRowTopDistanceFromTop = 0\n\t\t\tlet currentRowBottomDistanceFromTop = 0\n\n\t\t\t// Compute whether a row should be included in the DOM (shouldRender)\n\t\t\t// And how visible the row is.\n\t\t\treturn this.rows\n\t\t\t\t.reduce((visibleRows, row) => {\n\t\t\t\t\tcurrentRowTopDistanceFromTop = currentRowBottomDistanceFromTop\n\t\t\t\t\tcurrentRowBottomDistanceFromTop += row.height\n\n\t\t\t\t\tif (currentRowTopDistanceFromTop < scrollPosition - shouldRenderedWindow || scrollPosition + containerHeight + shouldRenderedWindow < currentRowTopDistanceFromTop) {\n\t\t\t\t\t\treturn visibleRows\n\t\t\t\t\t}\n\n\t\t\t\t\tlet visibility = 'none'\n\n\t\t\t\t\tif (scrollPosition - willBeVisibleWindow < currentRowTopDistanceFromTop && currentRowTopDistanceFromTop < scrollPosition + containerHeight + willBeVisibleWindow) {\n\t\t\t\t\t\tvisibility = 'near'\n\n\t\t\t\t\t\tif (scrollPosition - visibleWindow < currentRowTopDistanceFromTop && currentRowTopDistanceFromTop < scrollPosition + containerHeight + visibleWindow) {\n\t\t\t\t\t\t\tvisibility = 'visible'\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (scrollPosition - visibleWindow < currentRowBottomDistanceFromTop && currentRowBottomDistanceFromTop < scrollPosition + containerHeight + visibleWindow) {\n\t\t\t\t\t\t\tvisibility = 'visible'\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn [\n\t\t\t\t\t\t...visibleRows,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t...row,\n\t\t\t\t\t\t\tvisibility,\n\t\t\t\t\t\t},\n\t\t\t\t\t]\n\t\t\t\t}, [])\n\t\t},\n\n\t\t/**\n\t\t * Total height of all the rows + some room for the loader.\n\t\t *\n\t\t * @return {number}\n\t\t */\n\t\trowsHeight() {\n\t\t\tconst loaderHeight = 200\n\n\t\t\treturn this.rows\n\t\t\t\t.map(row => row.height)\n\t\t\t\t.reduce((totalHeight, rowHeight) => totalHeight + rowHeight, 0) + loaderHeight\n\t\t},\n\n\t\t/**\n\t\t * @return {number}\n\t\t */\n\t\tpaddingTop() {\n\t\t\tif (this.visibleRows.length === 0) {\n\t\t\t\treturn 0\n\t\t\t}\n\n\t\t\tconst firstVisibleRowIndex = this.rows.findIndex(row => row.items === this.visibleRows[0].items)\n\n\t\t\treturn this.rows\n\t\t\t\t.map(row => row.height)\n\t\t\t\t.slice(0, firstVisibleRowIndex)\n\t\t\t\t.reduce((totalHeight, rowHeight) => totalHeight + rowHeight, 0)\n\t\t},\n\n\t\t/**\n\t\t * padding-top is used to replace not included item in the container.\n\t\t *\n\t\t * @return {object}\n\t\t */\n\t\trowsContainerStyle() {\n\t\t\treturn {\n\t\t\t\theight: `${this.rowsHeight}px`,\n\t\t\t\tpaddingTop: `${this.paddingTop}px`,\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Whether the user is near the bottom.\n\t\t * If true, then the need-content event will be emitted.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tisNearBottom() {\n\t\t\tconst buffer = this.containerHeight * this.bottomBufferRatio\n\t\t\treturn this.scrollPosition + this.containerHeight >= this.rowsHeight - buffer\n\t\t},\n\n\t\t/**\n\t\t * @return {HTMLElement}\n\t\t */\n\t\tcontainer() {\n\t\t\tlogger.debug('[VirtualScrolling] Computing container')\n\t\t\tif (this.containerElement !== null) {\n\t\t\t\treturn this.containerElement\n\t\t\t} else if (this.useWindow) {\n\t\t\t\treturn window\n\t\t\t} else {\n\t\t\t\treturn this.$refs.container\n\t\t\t}\n\t\t},\n\t},\n\n\twatch: {\n\t\tisNearBottom(value) {\n\t\t\tif (value) {\n\t\t\t\tthis.$emit('need-content')\n\t\t\t}\n\t\t},\n\n\t\trows() {\n\t\t\t// Re-emit need-content when rows is updated and isNearBottom is still true.\n\t\t\t// If the height of added rows is under `bottomBufferRatio`, `isNearBottom` will still be true so we need more content.\n\t\t\tif (this.isNearBottom) {\n\t\t\t\tthis.$emit('need-content')\n\t\t\t}\n\t\t},\n\n\t\tscrollToKey(key) {\n\t\t\tlet currentRowTopDistanceFromTop = 0\n\t\t\tfor (const row of this.rows) {\n\t\t\t\tif (row.key === key) {\n\t\t\t\t\tthis.$refs.container.scrollTo({ top: currentRowTopDistanceFromTop, behavior: 'smooth' })\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tcurrentRowTopDistanceFromTop += row.height\n\t\t\t}\n\t\t},\n\t},\n\n\tmounted() {\n\t\tthis.resizeObserver = new ResizeObserver(entries => {\n\t\t\tfor (const entry of entries) {\n\t\t\t\tconst cr = entry.contentRect\n\t\t\t\tif (entry.target === this.container) {\n\t\t\t\t\tthis.containerHeight = cr.height\n\t\t\t\t}\n\t\t\t\tif (entry.target.classList.contains('vs-rows-container')) {\n\t\t\t\t\tthis.rowsContainerHeight = cr.height\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\n\t\tif (this.useWindow) {\n\t\t\twindow.addEventListener('resize', this.updateContainerSize)\n\t\t\tthis.containerHeight = window.innerHeight\n\t\t} else {\n\t\t\tthis.resizeObserver.observe(this.container)\n\t\t}\n\n\t\tthis.resizeObserver.observe(this.$refs.rowsContainer)\n\t\tthis.container.addEventListener('scroll', this.updateScrollPosition)\n\t},\n\n\tbeforeDestroy() {\n\t\tif (this.useWindow) {\n\t\t\twindow.removeEventListener('resize', this.updateContainerSize)\n\t\t}\n\n\t\tthis.resizeObserver.disconnect()\n\t\tthis.container.removeEventListener('scroll', this.updateScrollPosition)\n\t},\n\n\tmethods: {\n\t\tupdateScrollPosition: debounce(function() {\n\t\t\tif (this.useWindow) {\n\t\t\t\tthis.scrollPosition = this.container.scrollY\n\t\t\t} else {\n\t\t\t\tthis.scrollPosition = this.container.scrollTop\n\t\t\t}\n\t\t}, 200),\n\n\t\tupdateContainerSize() {\n\t\t\tthis.containerHeight = window.innerHeight\n\t\t},\n\t},\n}\n</script>\n\n<style scoped lang=\"scss\">\n.vs-container {\n\toverflow-y: scroll;\n\theight: 100%;\n}\n\n.vs-rows-container {\n\tbox-sizing: border-box;\n}\n</style>\n","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./VirtualScrolling.vue?vue&type=script&lang=js\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./VirtualScrolling.vue?vue&type=script&lang=js\"","\n import API from \"!../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/postcss-loader/dist/cjs.js!../../node_modules/sass-loader/dist/cjs.js??clonedRuleSet-2.use[3]!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./VirtualScrolling.vue?vue&type=style&index=0&id=7d847354&prod&scoped=true&lang=scss\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/postcss-loader/dist/cjs.js!../../node_modules/sass-loader/dist/cjs.js??clonedRuleSet-2.use[3]!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./VirtualScrolling.vue?vue&type=style&index=0&id=7d847354&prod&scoped=true&lang=scss\";\n export default content && content.locals ? content.locals : undefined;\n","import { render, staticRenderFns } from \"./VirtualScrolling.vue?vue&type=template&id=7d847354&scoped=true\"\nimport script from \"./VirtualScrolling.vue?vue&type=script&lang=js\"\nexport * from \"./VirtualScrolling.vue?vue&type=script&lang=js\"\nimport style0 from \"./VirtualScrolling.vue?vue&type=style&index=0&id=7d847354&prod&scoped=true&lang=scss\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"7d847354\",\n null\n \n)\n\nexport default component.exports","<!--\n - @copyright Copyright (c) 2022 Louis Chemineau <louis@chmn.me>\n -\n - @author Louis Chemineau <louis@chmn.me>\n -\n - @license AGPL-3.0-or-later\n -\n - This program is free software: you can redistribute it and/or modify\n - it under the terms of the GNU Affero General Public License as\n - published by the Free Software Foundation, either version 3 of the\n - License, or (at your option) any later version.\n -\n - This program is distributed in the hope that it will be useful,\n - but WITHOUT ANY WARRANTY; without even the implied warranty of\n - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n - GNU Affero General Public License for more details.\n -\n - You should have received a copy of the GNU Affero General Public License\n - along with this program. If not, see <http://www.gnu.org/licenses/>.\n -\n -->\n<template>\n\t<div class=\"files-list-viewer\">\n\t\t<NcEmptyContent v-if=\"emptyMessage !== '' && items.length === 0 && !loading\"\n\t\t\tkey=\"emptycontent\"\n\t\t\t:title=\"emptyMessage\">\n\t\t\t<PackageVariant slot=\"icon\" />\n\t\t</NcEmptyContent>\n\n\t\t<TiledLayout :base-height=\"baseHeight\" :items=\"items\">\n\t\t\t<VirtualScrolling slot-scope=\"{rows}\"\n\t\t\t\t:use-window=\"useWindow\"\n\t\t\t\t:container-element=\"containerElement\"\n\t\t\t\t:rows=\"rows\"\n\t\t\t\t:scroll-to-key=\"scrollToSection\"\n\t\t\t\t@need-content=\"needContent\">\n\t\t\t\t<ul slot-scope=\"{renderedRows}\">\n\t\t\t\t\t<template v-for=\"row of renderedRows\">\n\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\tWe are subtracting 1 from flex-basis to compensate for rounding issues.\n\t\t\t\t\t\t\tThe flex algo will then compensate with flex-grow.\n\t\t\t\t\t\t-->\n\t\t\t\t\t\t<li v-for=\"item of row.items\"\n\t\t\t\t\t\t\t:key=\"item.id\"\n\t\t\t\t\t\t\t:class=\"{'files-list-viewer__section-header': item.sectionHeader}\"\n\t\t\t\t\t\t\t:style=\"{ 'flex-basis': item.ratio ? `${row.height * item.ratio - 1}px` : '100%', height: `${row.height}px`}\">\n\t\t\t\t\t\t\t<!-- Placeholder when initial loading -->\n\t\t\t\t\t\t\t<div v-if=\"showPlaceholders\" class=\"files-list-viewer__placeholder\" />\n\t\t\t\t\t\t\t<!-- Real file. -->\n\t\t\t\t\t\t\t<slot v-else :file=\"item\" :visibility=\"row.visibility\" />\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</template>\n\t\t\t\t</ul>\n\t\t\t\t<NcLoadingIcon v-if=\"loading && !showPlaceholders\" slot=\"loader\" class=\"files-list-viewer__loader\" />\n\t\t\t</VirtualScrolling>\n\t\t</TiledLayout>\n\t</div>\n</template>\n<script>\nimport { mapActions, mapGetters } from 'vuex'\n\nimport PackageVariant from 'vue-material-design-icons/PackageVariant.vue'\n\nimport { NcEmptyContent, NcLoadingIcon } from '@nextcloud/vue'\nimport { subscribe, unsubscribe } from '@nextcloud/event-bus'\n\nimport TiledLayout from '../components/TiledLayout/TiledLayout.vue'\nimport { fetchFile } from '../services/fileFetcher.js'\nimport VirtualScrolling from '../components/VirtualScrolling.vue'\nimport EmptyBox from '../assets/Illustrations/empty.svg'\nimport UserConfig from '../mixins/UserConfig.js'\n\nexport default {\n\tname: 'FilesListViewer',\n\n\tcomponents: {\n\t\tPackageVariant,\n\t\tNcEmptyContent,\n\t\tNcLoadingIcon,\n\t\tTiledLayout,\n\t\tVirtualScrolling,\n\t},\n\n\tmixins: [UserConfig],\n\n\tprops: {\n\t\t// Array of file ids that should be rendered.\n\t\tfileIds: {\n\t\t\ttype: Array,\n\t\t\tdefault: undefined,\n\t\t},\n\t\t// An object mapping a list of section to a list of fileIds.\n\t\tfileIdsBySection: {\n\t\t\ttype: Object,\n\t\t\tdefault: undefined,\n\t\t},\n\t\t// The list of sorted sections.\n\t\tsections: {\n\t\t\ttype: Array,\n\t\t\tdefault: undefined,\n\t\t},\n\t\t// Whether we should display a loading indicator.\n\t\tloading: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t\t// Message to display when there is no files.\n\t\temptyMessage: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\t\t// The base height to forward to TileLayout.\n\t\tbaseHeight: {\n\t\t\ttype: Number,\n\t\t\tdefault: 200,\n\t\t},\n\t\t// The height to use for section headers.\n\t\tsectionHeaderHeight: {\n\t\t\ttype: Number,\n\t\t\tdefault: 75,\n\t\t},\n\t\t// Instruct VirtualScrolling to scroll to the given section id.\n\t\tscrollToSection: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\t\t// The containerElement props to forward to TileLayout.\n\t\tcontainerElement: {\n\t\t\ttype: HTMLElement,\n\t\t\tdefault: null,\n\t\t},\n\t\t// The useWindow props to forward to TileLayout.\n\t\tuseWindow: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\tEmptyBox,\n\t\t\tplaceholderFiles: Array(20).fill(0).map((_, index) => {\n\t\t\t\tconst height = 200\n\t\t\t\tconst width = this.croppedLayout ? height : height * (1 + Math.random() * 2)\n\t\t\t\treturn {\n\t\t\t\t\tid: index,\n\t\t\t\t\twidth,\n\t\t\t\t\theight,\n\t\t\t\t\tratio: width / height,\n\t\t\t\t}\n\t\t\t}),\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t...mapGetters([\n\t\t\t'files',\n\t\t]),\n\n\t\t/**\n\t\t * @return {object[]} The list of items to pass to TiledLayout.\n\t\t */\n\t\tfileIdsToItems() {\n\t\t\tif (this.fileIds === undefined) {\n\t\t\t\treturn []\n\t\t\t}\n\n\t\t\treturn this.fileIds\n\t\t\t\t.filter(fileId => this.files[fileId])\n\t\t\t\t.map(this.mapFileToItem)\n\t\t},\n\n\t\t/**\n\t\t * @return {object[]} The list of items separated by sections to pass to TiledLayout.\n\t\t */\n\t\tsectionsToItems() {\n\t\t\tif (this.sections === undefined) {\n\t\t\t\treturn []\n\t\t\t}\n\n\t\t\treturn this.sections.flatMap((sectionId) => {\n\t\t\t\treturn [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: sectionId,\n\t\t\t\t\t\tsectionHeader: true,\n\t\t\t\t\t\theight: this.sectionHeaderHeight,\n\t\t\t\t\t},\n\t\t\t\t\t...this.fileIdsBySection[sectionId]\n\t\t\t\t\t\t.filter(fileId => this.files[fileId])\n\t\t\t\t\t\t.map(this.mapFileToItem),\n\t\t\t\t]\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * @return {boolean} The list of items to pass to TiledLayout.\n\t\t */\n\t\tshowPlaceholders() {\n\t\t\treturn this.loading && (this.fileIds?.length === 0 || this.sections?.length === 0)\n\t\t},\n\n\t\t/**\n\t\t * @return {object[]} The list of items to pass to TiledLayout.\n\t\t */\n\t\titems() {\n\n\t\t\tif (this.fileIds !== undefined) {\n\t\t\t\tif (this.showPlaceholders) {\n\t\t\t\t\treturn this.placeholderFiles\n\t\t\t\t}\n\n\t\t\t\treturn this.fileIdsToItems\n\t\t\t}\n\n\t\t\tif (this.sections !== undefined) {\n\t\t\t\tif (this.showPlaceholders) {\n\t\t\t\t\treturn [{ height: 75, sectionHeader: true }, ...this.placeholderFiles]\n\t\t\t\t}\n\n\t\t\t\treturn this.sectionsToItems\n\t\t\t}\n\n\t\t\treturn []\n\t\t},\n\n\t\tshowLoader() {\n\t\t\treturn this.loading && (this.fileIds?.length !== 0 || this.sections?.length !== 0)\n\t\t},\n\t},\n\n\tmounted() {\n\t\tsubscribe('files:file:updated', this.handleFileUpdated)\n\t},\n\n\tdestroyed() {\n\t\tunsubscribe('files:file:updated', this.handleFileUpdated)\n\t},\n\n\tmethods: {\n\t\t...mapActions([\n\t\t\t'appendFiles',\n\t\t]),\n\n\t\t// Ask the parent for more content.\n\t\tneedContent() {\n\t\t\tthis.$emit('need-content')\n\t\t},\n\n\t\tmapFileToItem(fileId) {\n\t\t\tconst file = this.files[fileId]\n\t\t\treturn {\n\t\t\t\tid: file.fileid,\n\t\t\t\twidth: file.fileMetadataSizeParsed.width,\n\t\t\t\theight: file.fileMetadataSizeParsed.height,\n\t\t\t\tratio: this.croppedLayout ? 1 : file.fileMetadataSizeParsed.width / file.fileMetadataSizeParsed.height,\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * @param {object} data\n\t\t * @param {string} data.fileid - The file id of the updated file.\n\t\t */\n\t\tasync handleFileUpdated({ fileid }) {\n\t\t\tconst fetchedFile = await fetchFile(this.files[fileid].filename)\n\t\t\tthis.appendFiles([fetchedFile])\n\t\t},\n\t},\n}\n</script>\n<style lang=\"scss\" scoped>\n.files-list-viewer {\n\theight: 100%;\n\tposition: relative;\n\n\t&__placeholder {\n\t\tbackground: var(--color-primary-light);\n\t\twidth: 100%;\n\t\theight: 100%;\n\t\tborder: 2px solid var(--color-main-background); // Use border so create a separation between images.\n\t}\n\n\t.tiled-container {\n\t\tflex-basis: 0;\n\t}\n\n\tul {\n\t\tdisplay: flex;\n\t\tflex-wrap: wrap;\n\n\t\tli {\n\t\t\tflex-grow: 1;\n\t\t}\n\t}\n\n\t&__section-header {\n\t\tposition: sticky;\n\t\ttop: 0;\n\t\tz-index: 3;\n\t\tbackground: var(--color-main-background);\n\t}\n\n\t&__loader {\n\t\tmargin: 50px 0;\n\t}\n}\n</style>\n","import mod from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./FilesListViewer.vue?vue&type=script&lang=js\"; export default mod; export * from \"-!../../node_modules/babel-loader/lib/index.js!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./FilesListViewer.vue?vue&type=script&lang=js\"","\n import API from \"!../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/postcss-loader/dist/cjs.js!../../node_modules/sass-loader/dist/cjs.js??clonedRuleSet-2.use[3]!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./FilesListViewer.vue?vue&type=style&index=0&id=3ae373ae&prod&lang=scss&scoped=true\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../node_modules/css-loader/dist/cjs.js!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/postcss-loader/dist/cjs.js!../../node_modules/sass-loader/dist/cjs.js??clonedRuleSet-2.use[3]!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./FilesListViewer.vue?vue&type=style&index=0&id=3ae373ae&prod&lang=scss&scoped=true\";\n export default content && content.locals ? content.locals : undefined;\n","import { render, staticRenderFns } from \"./FilesListViewer.vue?vue&type=template&id=3ae373ae&scoped=true\"\nimport script from \"./FilesListViewer.vue?vue&type=script&lang=js\"\nexport * from \"./FilesListViewer.vue?vue&type=script&lang=js\"\nimport style0 from \"./FilesListViewer.vue?vue&type=style&index=0&id=3ae373ae&prod&lang=scss&scoped=true\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"3ae373ae\",\n null\n \n)\n\nexport default component.exports"],"names":["name","data","abortController","AbortController","beforeDestroy","this","abort","beforeRouteLeave","from","to","next","selection","watch","$route","resetSelection","methods","onFileSelectToggle","_ref","id","value","$set","onUncheckFiles","filesIds","forEach","filesId","computed","selectedFileIds","Object","keys","filter","fileId","eventName","croppedLayoutLocalStorage","localStorage","getItem","croppedLayout","loadState","photosLocation","created","subscribe","updateLocalSetting","unsubscribe","setting","updateSetting","axios","generateUrl","toString","setItem","emit","___CSS_LOADER_EXPORT___","push","module","components","NcCheckboxRadioSwitch","Star","VideoIcon","inheritAttrs","props","file","type","required","selected","Boolean","allowSelection","default","visibility","String","semaphore","Semaphore","loadedNear","loadedVisible","errorNear","errorVisible","canLoad","semaphoreSymbol","isDestroyed","ariaDescription","concat","fileid","ariaLabel","t","basename","isImage","mime","startsWith","decodedEtag","etag","replace","srcVisible","getItemURL","srcNear","acquire","releaseSemaphore","undefined","$refs","imgNear","src","emitClick","$emit","onLoadNear","onLoadVisible","onErrorNear","onErrorVisible","onToggle","size","token","params","release","options","styleTagTransform","setAttributes","insert","domAPI","insertStyleElement","_vm","_c","_self","staticClass","class","attrs","source","on","$event","stopPropagation","preventDefault","apply","arguments","includes","_e","_v","key","ref","show","_s","imageName","favorite","computeRowWidth","items","baseHeight","map","item","ratio","reduce","sum","itemWidth","computeRowHeight","containerWidth","isLastRow","length","sectionHeader","height","rowHeight","itemRatio","width","Math","min","TiledRows","_l","rows","row","style","_t","Array","Number","resizeObserver","logger","rowNumber","currentItem","rowItems","join","splitItemsInRows","mounted","ResizeObserver","entries","entry","cr","contentRect","target","classList","contains","observe","tiledLayoutContainer","disconnect","getCollectionFilesDavRequest","containerElement","HTMLElement","useWindow","renderWindowRatio","willBeVisibleWindowRatio","visibleWindowRatio","bottomBufferRatio","scrollToKey","scrollPosition","containerHeight","rowsContainerHeight","visibleRows","shouldRenderedWindow","willBeVisibleWindow","visibleWindow","currentRowTopDistanceFromTop","currentRowBottomDistanceFromTop","rowsHeight","totalHeight","paddingTop","firstVisibleRowIndex","findIndex","slice","rowsContainerStyle","isNearBottom","buffer","container","window","scrollTo","top","behavior","addEventListener","updateContainerSize","innerHeight","rowsContainer","updateScrollPosition","removeEventListener","debounce","scrollY","scrollTop","PackageVariant","NcEmptyContent","NcLoadingIcon","TiledLayout","VirtualScrolling","mixins","UserConfig","fileIds","fileIdsBySection","sections","loading","emptyMessage","sectionHeaderHeight","scrollToSection","EmptyBox","placeholderFiles","fill","_","index","random","mapGetters","fileIdsToItems","files","mapFileToItem","sectionsToItems","flatMap","sectionId","showPlaceholders","_this$fileIds","_this$sections","showLoader","_this$fileIds2","_this$sections2","handleFileUpdated","destroyed","mapActions","needContent","fileMetadataSizeParsed","fetchedFile","async","fileName","response","defaultClient","details","genFileInfo","error","code","fetchFile","filename","appendFiles","slot","scopedSlots","_u","fn","_ref2","renderedRows"],"sourceRoot":""}