diff options
author | John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> | 2019-11-12 07:12:36 +0100 |
---|---|---|
committer | John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> | 2019-11-13 08:45:29 +0100 |
commit | 2366aaf6ad5d607762f9453884bfb600f13b2c93 (patch) | |
tree | e318f5f0cb18a4444479f24e134730961eddd6a1 | |
parent | ae28cc9b2d79568ae069e3f25ed29791986791d0 (diff) |
Tags
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
-rw-r--r-- | css/icons.scss | 2 | ||||
-rw-r--r-- | img/photos.svg | 2 | ||||
-rw-r--r-- | package-lock.json | 3 | ||||
-rw-r--r-- | package.json | 1 | ||||
-rw-r--r-- | src/Photos.vue | 2 | ||||
-rw-r--r-- | src/components/Folder.vue | 31 | ||||
-rw-r--r-- | src/components/Navigation.vue | 13 | ||||
-rw-r--r-- | src/patchedRequest.js | 3 | ||||
-rw-r--r-- | src/router/index.js | 20 | ||||
-rw-r--r-- | src/services/FileList.js | 8 | ||||
-rw-r--r-- | src/services/FolderInfo.js | 4 | ||||
-rw-r--r-- | src/services/PhotoSearch.js | 2 | ||||
-rw-r--r-- | src/services/SystemTags.js | 22 | ||||
-rw-r--r-- | src/store/folders.js | 5 | ||||
-rw-r--r-- | src/store/systemtags.js | 66 | ||||
-rw-r--r-- | src/utils/fileUtils.js | 125 | ||||
-rw-r--r-- | src/utils/numberUtil.js (renamed from src/utils/ParseFile.js) | 21 | ||||
-rw-r--r-- | src/views/Albums.vue | 2 | ||||
-rw-r--r-- | src/views/Tags.vue | 71 | ||||
-rw-r--r-- | webpack.common.js | 1 |
20 files changed, 288 insertions, 116 deletions
diff --git a/css/icons.scss b/css/icons.scss index 88e42707..ba8dcef9 100644 --- a/css/icons.scss +++ b/css/icons.scss @@ -24,4 +24,4 @@ @include icon-color('folder', 'filetypes', $color-black, 1, true); } -@include icon-black-white('photos', 'photos', 1); +@include icon-black-white('photos', 'photos', 2); diff --git a/img/photos.svg b/img/photos.svg index 90c3fdb6..6046f92b 100644 --- a/img/photos.svg +++ b/img/photos.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" height="32" width="32" version="1"><g transform="translate(-11.5 2.5)"><path d="M20.5 7.5a1 1 0 00-1 1v17c0 .5.6 1 1 1h20c.5 0 1-.5 1-1v-17c0-.4-.5-1-1-1zM21 9h19v14.5H21z"/><circle cx="24.8" cy="13" r="2.3"/><path d="M38.4 15.5L35 20.2 33.6 22l-1.2-1.4-3.5-3.5-4.5 4.3-3.6 3.3h19.9v-6.6zM14.5 2.5a1 1 0 00-1 1v17c0 .5.6 1 1 1h6v-3H15V4h19v3.5h1.5v-4c0-.4-.5-1-1-1h-20z"/></g></svg>
\ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" height="32" width="32" version="1"><g transform="translate(-11.5 2.5)"><path d="M20.5 7.5a1 1 0 00-1 1v17c0 .5.6 1 1 1h20c.5 0 1-.5 1-1v-17c0-.4-.5-1-1-1zM21 9h19v14.5H21z"/><circle cx="24.8" cy="13" r="2.3"/><path d="M38.4 15.5L35 20.2 33.6 22l-1.2-1.4-3.5-3.5-4.5 4.3-3.6 3.3h19.9v-6.6l-2.3-2.6zM14.5.5a1 1 0 00-1 1v17c0 .5.6 1 1 1h5.9v-3H15V2h19v6.6h1.5V1.5c0-.4-.5-1-1-1h-20z"/></g></svg>
\ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 39a3b402..7a8031b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1853,8 +1853,7 @@ "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, "camelcase-keys": { "version": "2.1.0", diff --git a/package.json b/package.json index abc6819f..4ee8bf4a 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "@nextcloud/l10n": "^0.2.1", "@nextcloud/router": "^0.1.0", "@nextcloud/vue": "^1.1.0", + "camelcase": "^5.3.1", "cdav-library": "git+https://github.com/nextcloud/cdav-library.git", "path-posix": "^1.0.0", "qs": "^6.9.0", diff --git a/src/Photos.vue b/src/Photos.vue index ec26f323..49b83e13 100644 --- a/src/Photos.vue +++ b/src/Photos.vue @@ -30,7 +30,7 @@ <AppNavigationItem to="/favorites" :title="t('photos', 'Favorites')" icon="icon-favorite" /> <AppNavigationItem :to="{name: 'albums'}" :title="t('photos', 'Your albums')" icon="icon-files-dark" /> <AppNavigationItem :to="{name: 'shared'}" :title="t('photos', 'Shared albums')" icon="icon-share" /> - <AppNavigationItem :to="{name: 'tags'}" :title="t('photos', 'Tags')" icon="icon-tag" /> + <AppNavigationItem :to="{name: 'tags'}" :title="t('photos', 'Tagged photos')" icon="icon-tag" /> <AppNavigationItem :to="{name: 'maps'}" :title="t('photos', 'Locations')" icon="icon-address" /> </AppNavigation> <AppContent :class="{ 'icon-loading': loading }"> diff --git a/src/components/Folder.vue b/src/components/Folder.vue index de2db5a6..c04e17a9 100644 --- a/src/components/Folder.vue +++ b/src/components/Folder.vue @@ -43,7 +43,7 @@ class="folder-name__icon" role="img" /> <p :id="ariaUuid" class="folder-name__name"> - {{ folder.basename }} + {{ basename }} </p> </div> <div class="cover" role="none" /> @@ -62,8 +62,16 @@ export default { inheritAttrs: false, props: { - folder: { - type: Object, + basename: { + type: String, + required: true, + }, + filename: { + type: String, + required: true, + }, + id: { + type: Number, required: true, }, icon: { @@ -88,7 +96,7 @@ export default { // files list of the current folder folderContent() { - return this.folders[this.folder.id] + return this.folders[this.id] }, fileList() { return this.folderContent @@ -105,23 +113,24 @@ export default { }, ariaUuid() { - return `folder-${this.folder.id}` + return `folder-${this.id}` }, ariaLabel() { - return t('photos', 'Open the "{name}" sub-directory', { name: this.folder.basename }) + return t('photos', 'Open the "{name}" sub-directory', { name: this.basename }) }, /** * We do not want encoded slashes when browsing by folder * so we generate a new valid route object, get the final url back - * decode it and use it as a direct string, which vue-router + * decode it and use it as a direct string, which vue-router * does not encode afterwards + * @returns {string} */ to() { const route = Object.assign({}, this.$route, { // always remove first slash - params: { path: this.folder.filename.substr(1) } - }); + params: { path: this.filename.substr(1) }, + }) return decodeURIComponent(this.$router.resolve(route).resolved.path) }, }, @@ -133,9 +142,9 @@ export default { try { // get data - const { files, folders } = await request(this.folder.filename) + const { files, folders } = await request(this.filename) // this.cancelRequest('Stop!') - this.$store.dispatch('updateFolders', { id: this.folder.id, files, folders }) + this.$store.dispatch('updateFolders', { id: this.id, files, folders }) this.$store.dispatch('updateFiles', { folder: this.folder, files, folders }) } catch (error) { if (error.response && error.response.status) { diff --git a/src/components/Navigation.vue b/src/components/Navigation.vue index df1c3f0f..a0d4c92c 100644 --- a/src/components/Navigation.vue +++ b/src/components/Navigation.vue @@ -56,6 +56,10 @@ export default { type: String, required: true, }, + rootTitle: { + type: String, + default: t('photos', 'Photos'), + }, id: { type: Number, required: true, @@ -68,7 +72,7 @@ export default { }, name() { if (this.isRoot) { - return t('photos', 'Photos') + return this.rootTitle } return this.basename }, @@ -93,14 +97,15 @@ export default { /** * We do not want encoded slashes when browsing by folder * so we generate a new valid route object, get the final url back - * decode it and use it as a direct string, which vue-router + * decode it and use it as a direct string, which vue-router * does not encode afterwards + * @returns {string} */ to() { const route = Object.assign({}, this.$route, { // always remove first slash - params: { path: this.parentPath.substr(1) } - }); + params: { path: this.parentPath.substr(1) }, + }) return decodeURIComponent(this.$router.resolve(route).resolved.path) }, }, diff --git a/src/patchedRequest.js b/src/patchedRequest.js index 6b1eb267..ae23b19d 100644 --- a/src/patchedRequest.js +++ b/src/patchedRequest.js @@ -21,7 +21,6 @@ */ const request = require('webdav/dist/request') -const merge = require('webdav/dist/merge') const oldPrepareRequestOptions = request.prepareRequestOptions @@ -32,7 +31,7 @@ const oldPrepareRequestOptions = request.prepareRequestOptions request.prepareRequestOptions = function(requestOptions, methodOptions) { // add our cancelToken support if (methodOptions.cancelToken && typeof methodOptions.cancelToken === 'object') { - requestOptions.cancelToken = merge(requestOptions.cancelToken || {}, methodOptions.cancelToken) + requestOptions.cancelToken = Object.assign({}, requestOptions.cancelToken || {}, methodOptions.cancelToken) } // exploit old method oldPrepareRequestOptions(requestOptions, methodOptions) diff --git a/src/router/index.js b/src/router/index.js index df464138..d4d9caa6 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -55,7 +55,7 @@ export default new Router({ children: [ { path: ':path*', - name: 'path', + name: 'albumspath', component: Albums, }, ], @@ -68,7 +68,7 @@ export default new Router({ children: [ { path: ':path*', - name: 'path', + name: 'sharedpath', component: Albums, }, ], @@ -77,24 +77,18 @@ export default new Router({ path: '/favorites', component: Tags, name: 'favorites', - props, - children: [ - { - path: ':path*', - name: 'path', - component: Tags, - }, - ], }, { path: '/tags', component: Tags, name: 'tags', - props, + props: route => ({ + tagname: route.params.tagname, + }), children: [ { - path: ':path*', - name: 'path', + path: ':tagname', + name: 'tagname', component: Tags, }, ], diff --git a/src/services/FileList.js b/src/services/FileList.js index 80e9df6d..c473aad8 100644 --- a/src/services/FileList.js +++ b/src/services/FileList.js @@ -26,8 +26,7 @@ import { handleResponseCode, processResponsePayload } from 'webdav/dist/response import { normaliseHREF, normalisePath } from 'webdav/dist/url' import client, { remotePath } from './DavClient' import pathPosix from 'path-posix' -import request from './DavRequest' -import parseFile from '../utils/ParseFile' +import { genFileInfo } from '../utils/fileUtils' /** * List files from a folder and filter out unwanted mimes @@ -37,6 +36,8 @@ import parseFile from '../utils/ParseFile' * @returns {Array} the file list */ export default async function(path, options) { + + console.trace(); options = Object.assign({ method: 'PROPFIND', headers: { @@ -44,7 +45,6 @@ export default async function(path, options) { Depth: options.deep ? 'infinity' : 1, }, responseType: 'text', - data: request, details: true, }, options) @@ -68,7 +68,7 @@ export default async function(path, options) { .then(result => getDirectoryFiles(result, remotePath, options.details)) .then(files => processResponsePayload(response, files, options.details)) - const list = data.map(data => parseFile(data, prefixPath)) + const list = data.map(data => genFileInfo(data, prefixPath)) // filter all the files and folders let folder = {} diff --git a/src/services/FolderInfo.js b/src/services/FolderInfo.js index 6d65b57a..b58ddb79 100644 --- a/src/services/FolderInfo.js +++ b/src/services/FolderInfo.js @@ -23,7 +23,7 @@ import { getCurrentUser } from '@nextcloud/auth' import client from './DavClient' import request from './DavRequest' -import parseFile from '../utils/ParseFile' +import { genFileInfo } from '../utils/fileUtils' /** * List files from a folder and filter out unwanted mimes @@ -43,5 +43,5 @@ export default async function(path) { details: true, }) - return parseFile(response.data, prefixPath) + return genFileInfo(response.data, prefixPath) } diff --git a/src/services/PhotoSearch.js b/src/services/PhotoSearch.js index e4546bb4..8d3789ea 100644 --- a/src/services/PhotoSearch.js +++ b/src/services/PhotoSearch.js @@ -23,7 +23,7 @@ import { generateRemoteUrl } from '@nextcloud/router' import { getCurrentUser } from '@nextcloud/auth' import client from './DavClient' -import parseFile from '../utils/ParseFile' +import { genFileInfo } from '../utils/fileUtils' /** * List files from a folder and filter out unwanted mimes diff --git a/src/services/SystemTags.js b/src/services/SystemTags.js index a8ce55eb..c0244a31 100644 --- a/src/services/SystemTags.js +++ b/src/services/SystemTags.js @@ -21,15 +21,17 @@ */ import client from './DavClient' -import { generateRemoteUrl } from '@nextcloud/router' +import { genFileInfo } from '../utils/fileUtils' /** - * List files from a folder and filter out unwanted mimes + * List system tags * + * @param {String} path the path relative to the user root + * @param {Object} [options] optional options for axios * @returns {Array} the file list */ -export default async function() { - const response = await client.getDirectoryContents('/systemtags/', { +export default async function(path, options = {}) { + const response = await client.getDirectoryContents('/systemtags/', Object.assign({}, { data: `<?xml version="1.0"?> <d:propfind xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns"> @@ -42,15 +44,7 @@ export default async function() { </d:prop> </d:propfind>`, details: true, - }) - - console.info(response) - - const entry = response.data - return Object.assign({ - id: parseInt(entry.props.fileid), - isFavorite: entry.props.favorite !== '0', - hasPreview: entry.props['has-preview'] !== 'false', - }, entry) + }, options)) + return response.data.map(data => genFileInfo(data)) } diff --git a/src/store/folders.js b/src/store/folders.js index 559d3ef2..1075900d 100644 --- a/src/store/folders.js +++ b/src/store/folders.js @@ -20,6 +20,7 @@ * */ import Vue from 'vue' +import { sortCompare } from '../utils/fileUtils' const state = { paths: {}, @@ -39,9 +40,7 @@ const mutations = { if (files.length > 0) { const t0 = performance.now() // sort by last modified - const list = files.sort((a, b) => { - return new Date(b.lastmod).getTime() - new Date(a.lastmod).getTime() - }) + const list = files.sort((a, b) => sortCompare(a, b, 'lastmod')) // Set folder list Vue.set(state.folders, id, list.map(file => file.id)) diff --git a/src/store/systemtags.js b/src/store/systemtags.js index 8f213e9e..4a49e13e 100644 --- a/src/store/systemtags.js +++ b/src/store/systemtags.js @@ -20,50 +20,56 @@ * */ import Vue from 'vue' +import { sortCompare } from '../utils/fileUtils' const state = { - paths: {}, tags: {}, + names: {}, } const mutations = { /** - * Index folders paths and ids + * Order and save tags * * @param {Object} state vuex state - * @param {Object} data destructuring object - * @param {number} data.id current folder id - * @param {Array} data.files list of files + * @param {Array} tags the tags list */ - updateTags(state, { id, files }) { - if (files.length > 0) { - // sort by last modified - const list = files.sort((a, b) => { - return new Date(b.lastmod).getTime() - new Date(a.lastmod).getTime() - }) + updateTags(state, tags) { + if (tags.length > 0) { + // sort by basename + const list = tags.sort((a, b) => sortCompare(a, b, 'displayName')) - // Set folder list - Vue.set(state.tags, id, list.map(file => file.id)) + // store tag and its index + list.forEach(tag => { + Vue.set(state.tags, tag.id, tag) + Vue.set(state.tags[tag.id], 'files', []) + Vue.set(state.names, tag.displayName, tag.id) + }) } }, /** - * Index folders paths and ids + * Update tag files list * * @param {Object} state vuex state * @param {Object} data destructuring object - * @param {string} data.path path of this folder - * @param {number} data.id id of this folder + * @param {number} data.id current tag id + * @param {Object[]} data.files list of files */ - addPath(state, { path, id }) { - Vue.set(state.paths, path, id) + updateTag(state, { id, files }) { + // sort by last modified + const list = files.sort((a, b) => sortCompare(a, b, 'lastmod')) + + // overwrite list + Vue.set(state.tags[id], 'files', list.map(file => file.id)) }, } const getters = { tags: state => state.tags, + tagsNames: state => state.names, tag: state => id => state.tags[id], - tagId: state => path => state.paths[path], + tagId: state => name => state.names[name], } const actions = { @@ -71,28 +77,22 @@ const actions = { * Update files and folders * * @param {Object} context vuex context - * @param {Object} data destructuring object - * @param {number} data.id current folder id - * @param {Array} data.files list of files - * @param {Array} data.folders list of folders + * @param {Array} tags the tag list */ - updateTags(context, { id, files, folders }) { - context.commit('updateTags', { id, files }) - - // then add each folders path indexes - folders.forEach(folder => context.commit('addPath', { path: folder.filename, id: folder.id })) + updateTags(context, tags) { + context.commit('updateTags', tags) }, /** - * Index folders paths and ids + * Update tag files list * * @param {Object} context vuex context * @param {Object} data destructuring object - * @param {string} data.path path of this folder - * @param {number} data.id id of this folder + * @param {number} data.id current tag id + * @param {Object[]} data.files list of files */ - addPath(context, { path, id }) { - context.commit('addPath', { path, id }) + updateTag(context, { id, files }) { + context.commit('updateTag', { id, files }) }, } diff --git a/src/utils/fileUtils.js b/src/utils/fileUtils.js new file mode 100644 index 00000000..ce18c08f --- /dev/null +++ b/src/utils/fileUtils.js @@ -0,0 +1,125 @@ +/** + * @copyright Copyright (c) 2019 John Molakvoæ <skjnldsv@protonmail.com> + * + * @author John Molakvoæ <skjnldsv@protonmail.com> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +import camelcase from 'camelcase' +import { isNumber } from './numberUtil' + +/** + * Get an url encoded path + * + * @param {String} path the full path + * @returns {string} url encoded file path + */ +const encodeFilePath = function(path) { + const pathSections = (path.startsWith('/') ? path : `/${path}`).split('/') + let relativePath = '' + pathSections.forEach((section) => { + if (section !== '') { + relativePath += '/' + encodeURIComponent(section) + } + }) + return relativePath +} + +/** + * Extract dir and name from file path + * + * @param {String} path the full path + * @returns {String[]} [dirPath, fileName] + */ +const extractFilePaths = function(path) { + const pathSections = path.split('/') + const fileName = pathSections[pathSections.length - 1] + const dirPath = pathSections.slice(0, pathSections.length - 1).join('/') + return [dirPath, fileName] +} + +/** + * Sorting comparison function + * + * @param {Object} fileInfo1 file 1 fileinfo + * @param {Object} fileInfo2 file 2 fileinfo + * @param {string} key key to sort with + * @param {boolean} [asc=true] sort ascending? + * @returns {number} + */ +const sortCompare = function(fileInfo1, fileInfo2, key, asc = true) { + + // favorite always first + if (fileInfo1.isFavorite && !fileInfo2.isFavorite) { + return -1 + } else if (!fileInfo1.isFavorite && fileInfo2.isFavorite) { + return 1 + } + + // if this is a number, let's sort by integer + if (isNumber(fileInfo1[key]) && isNumber(fileInfo2[key])) { + return asc + ? Number(fileInfo2[key]) - Number(fileInfo1[key]) + : Number(fileInfo1[key]) - Number(fileInfo2[key]) + } + + // else we sort by string, so let's sort directories first + if (fileInfo1.type === 'directory' && fileInfo2.type !== 'directory') { + return asc ? -1 : 1 + } else if (fileInfo1.type !== 'directory' && fileInfo2.type === 'directory') { + return asc ? 1 : -1 + } + + // if this is a date, let's sort by date + if (isNumber(new Date(fileInfo1[key]).getTime()) && isNumber(new Date(fileInfo2[key])).getTime()) { + return asc + ? new Date(fileInfo2[key]).getTime() - new Date(fileInfo1[key]).getTime() + : new Date(fileInfo1[key]).getTime() - new Date(fileInfo2[key]).getTime() + } + + // finally sort by name + return asc + ? fileInfo1[key].localeCompare(fileInfo2[key], OC.getLanguage()) + : -fileInfo1[key].localeCompare(fileInfo2[key], OC.getLanguage()) +} + +const genFileInfo = function(obj) { + const fileInfo = {} + + Object.keys(obj).forEach(key => { + const data = obj[key] + + // flatten object if any + if (!!data && typeof data === 'object') { + Object.assign(fileInfo, genFileInfo(data)) + } else { + // format key and add it to the fileInfo + if (data === 'false') { + fileInfo[camelcase(key)] = false + } else if (data === 'true') { + fileInfo[camelcase(key)] = true + } else { + fileInfo[camelcase(key)] = isNumber(data) + ? Number(data) + : data + } + } + }) + return fileInfo +} + +export { encodeFilePath, extractFilePaths, sortCompare, genFileInfo } diff --git a/src/utils/ParseFile.js b/src/utils/numberUtil.js index 8d9d9baf..0c3a96e5 100644 --- a/src/utils/ParseFile.js +++ b/src/utils/numberUtil.js @@ -20,18 +20,11 @@ * */ -/** - * Format a file into a usable fileinfo object - * - * @param {Object} fileData file data returned by the webdav lib - * @param {String} prefixPath path to substract from the files - * @returns {Object} - */ -export default function(fileData, prefixPath = '') { - const filename = fileData.filename.replace(prefixPath, '/').replace(/^\/\//, '/') - return Object.assign({ - id: parseInt(fileData.props.fileid), - isFavorite: fileData.props.favorite !== '0', - hasPreview: fileData.props['has-preview'] !== 'false', - }, fileData, { filename }) +const isNumber = function(num) { + if (!num) { + return false + } + return Number(num).toString() === num.toString() } + +export { isNumber } diff --git a/src/views/Albums.vue b/src/views/Albums.vue index 98642e3d..2338a3c7 100644 --- a/src/views/Albums.vue +++ b/src/views/Albums.vue @@ -35,7 +35,7 @@ <!-- Folder content --> <Grid v-else> <Navigation v-if="folder" key="navigation" v-bind="folder" /> - <Folder v-for="dir in folderList" :key="dir.id" :folder="dir" /> + <Folder v-for="dir in folderList" :key="dir.id" v-bind="dir" /> <File v-for="file in fileList" :key="file.id" v-bind="file" /> </Grid> </template> diff --git a/src/views/Tags.vue b/src/views/Tags.vue index 8180b2bc..069b99f4 100644 --- a/src/views/Tags.vue +++ b/src/views/Tags.vue @@ -33,12 +33,23 @@ </EmptyContent> --> <!-- Folder content --> + <Grid v-if="isRoot"> + <Navigation v-if="tag" + key="navigation" + :basename="tagname" + :filename="'/' + tagname" + :root-title="t('photos', 'Tags')" /> + <Folder v-for="id in tagsNames" + :key="id" + v-bind="tags[id]" + :basename="tags[id].displayName" + icon="icon-tag" /> + </Grid> <!-- <Grid v-else> <Navigation v-if="folder" key="navigation" v-bind="folder" /> <Folder v-for="dir in folderList" :key="dir.id" :folder="dir" /> <File v-for="file in fileList" :key="file.id" v-bind="file" /> </Grid> --> - <span>Test</span> </template> <script> @@ -64,9 +75,9 @@ export default { Navigation, } |