← Back
Editing: TagsView-DUUPrt_d.chunk.mjs.map
{"version":3,"file":"TagsView-DUUPrt_d.chunk.mjs","sources":["../src/components/TagCover.vue","../src/views/TagsView.vue"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n - SPDX-License-Identifier: AGPL-3.0-or-later\n-->\n\n<template>\n\t<RouterLink class=\"tag-cover\" :to=\"`/tags/${tag.attributes['display-name']}`\">\n\t\t<img\n\t\t\tv-if=\"tag.attributes['files-assigned'] !== 0\"\n\t\t\tclass=\"tag-cover__image\"\n\t\t\t:src=\"coverUrl\">\n\t\t<div v-else class=\"tag-cover__image tag-cover__image--placeholder\">\n\t\t\t<ImageMultipleOutline :size=\"128\" />\n\t\t</div>\n\t\t<div class=\"tag-cover__details\">\n\t\t\t<div class=\"tag-cover__details__first-line\">\n\t\t\t\t<h3 class=\"tag-cover__details__name\">\n\t\t\t\t\t{{ t('recognize', tag.attributes['display-name']) }}\n\t\t\t\t</h3>\n\t\t\t</div>\n\t\t\t<div class=\"tag-cover__details__second-line\">\n\t\t\t\t{{ n('photos', '%n photo', '%n photos', count) }}\n\t\t\t</div>\n\t\t</div>\n\t</RouterLink>\n</template>\n\n<script lang='ts'>\nimport type { Tag } from '../store/systemtags.js'\n\nimport { translatePlural as n, translate as t } from '@nextcloud/l10n'\nimport { generateUrl } from '@nextcloud/router'\nimport {\n\ttype PropType,\n\n\tdefineComponent,\n} from 'vue'\nimport { RouterLink } from 'vue-router'\nimport ImageMultipleOutline from 'vue-material-design-icons/ImageMultipleOutline.vue'\nimport AbortControllerMixin from '../mixins/AbortControllerMixin.js'\n\nexport default defineComponent({\n\tname: 'TagCover',\n\n\tcomponents: {\n\t\tRouterLink,\n\t\tImageMultipleOutline,\n\t},\n\n\tmixins: [AbortControllerMixin],\n\n\tprops: {\n\t\ttag: {\n\t\t\ttype: Object as PropType<Tag>,\n\t\t\trequired: true,\n\t\t},\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\tloadCover: false,\n\t\t\tobserver: null as IntersectionObserver | null,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\ttags() {\n\t\t\treturn this.$store.state.systemtags.tags\n\t\t},\n\n\t\tfiles() {\n\t\t\treturn this.$store.state.files.files\n\t\t},\n\n\t\tcoverUrl(): string {\n\t\t\tif (!this.loadCover) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn generateUrl(`/core/preview?fileId=${this.tag.attributes['reference-fileid']}&x=${512}&y=${512}&forceIcon=0&a=1`)\n\t\t},\n\n\t\tcount() {\n\t\t\treturn this.tag.attributes['files-assigned']\n\t\t},\n\t},\n\n\twatch: {\n\t\tloadCover() {\n\t\t\tif (this.tag.attributes['files-assigned']) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.$store.dispatch('fetchTagFiles', { id: this.tag.attributes.id, signal: this.abortController.signal })\n\t\t},\n\t},\n\n\tmounted() {\n\t\tthis.observer = new IntersectionObserver((entries) => {\n\t\t\tif (entries[0].isIntersecting) {\n\t\t\t\tthis.loadCover = true\n\t\t\t\tthis.observer?.disconnect()\n\t\t\t}\n\t\t})\n\t\tthis.observer.observe(this.$el)\n\t},\n\n\tmethods: {\n\t\tt,\n\t\tn,\n\t},\n})\n</script>\n\n<style scoped lang=\"scss\">\n.tag-cover {\n\tdisplay: flex;\n\tflex-direction: column;\n\tpadding: 16px;\n\tborder-radius: 12px;\n\n\t&:hover, &:focus {\n\t\tbackground: var(--color-background-dark);\n\t}\n\n\t&__image {\n\t\twidth: 350px;\n\t\theight: 350px;\n\t\tobject-fit: cover;\n\t\tborder-radius: 12px;\n\n\t\t@media only screen and (max-width: 1200px) {\n\t\t\twidth: 250px;\n\t\t\theight: 250px;\n\t\t}\n\n\t\t&--placeholder {\n\t\t\tbackground: var(--color-primary-element-light);\n\n\t\t\t:deep(.material-design-icon) {\n\t\t\t\twidth: 100%;\n\t\t\t\theight: 100%;\n\n\t\t\t\t.material-design-icon__svg {\n\t\t\t\t\tfill: var(--color-primary-element);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t&__details {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tmargin-top: 16px;\n\t\twidth: 350px;\n\n\t\t@media only screen and (max-width: 1200px) {\n\t\t\twidth: 250px;\n\t\t}\n\n\t\t&__first-line {\n\t\t\tdisplay: flex;\n\t\t}\n\n\t\t&__second-line {\n\t\t\tdisplay: flex;\n\t\t\tcolor: var(--color-text-lighter);\n\t\t}\n\n\t\t&__name {\n\t\t\tflex-grow: 1;\n\t\t\tmargin: 0;\n\t\t\tfont-weight: normal;\n\t\t\toverflow: hidden;\n\t\t\twhite-space: nowrap;\n\t\t\ttext-overflow: ellipsis;\n\n\t\t}\n\t}\n\n}\n</style>\n","<!--\n - SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n - SPDX-License-Identifier: AGPL-3.0-or-later\n-->\n\n<template>\n\t<div>\n\t\t<!-- Errors handlers-->\n\t\t<NcEmptyContent v-if=\"error\" :name=\"t('photos', 'An error occurred')\" />\n\n\t\t<NcEmptyContent v-if=\"!loading && tagsList.length === 0\" :name=\"t('photos', 'No tags yet')\" :description=\"t('photos', 'Photos with tags will show up here')\" />\n\n\t\t<NcLoadingIcon v-if=\"loading\" class=\"loader\" />\n\n\t\t<div v-else class=\"container\">\n\t\t\t<h2 v-if=\"popularTags.length\">\n\t\t\t\t{{ t('photos', 'Popular tags') }}\n\t\t\t</h2>\n\t\t\t<div class=\"popular-tags\">\n\t\t\t\t<TagCover v-for=\"tag in popularTags\" :key=\"tag.attributes.id\" :tag=\"tag\" />\n\t\t\t</div>\n\t\t\t<h2 v-if=\"tagsList.length\">\n\t\t\t\t{{ t('photos', 'All tags') }}\n\t\t\t</h2>\n\t\t\t<div class=\"tags\">\n\t\t\t\t<TagCover v-for=\"tag in tagsList\" :key=\"tag.attributes.id\" :tag=\"tag\" />\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</template>\n\n<script lang='ts'>\nimport { t } from '@nextcloud/l10n'\nimport { defineComponent } from 'vue'\nimport NcEmptyContent from '@nextcloud/vue/components/NcEmptyContent'\nimport NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon'\nimport TagCover from '../components/TagCover.vue'\nimport AbortControllerMixin from '../mixins/AbortControllerMixin.js'\nimport logger from '../services/logger.js'\n\nexport default defineComponent({\n\tname: 'TagsView',\n\tcomponents: {\n\t\tTagCover,\n\t\tNcLoadingIcon,\n\t\tNcEmptyContent,\n\t},\n\n\tmixins: [AbortControllerMixin],\n\n\tdata() {\n\t\treturn {\n\t\t\terror: null as boolean | null,\n\t\t\tloading: false,\n\t\t\tshowTags: false,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\tfiles() {\n\t\t\treturn this.$store.state.files.files\n\t\t},\n\n\t\ttags() {\n\t\t\treturn this.$store.state.systemtags.tags\n\t\t},\n\n\t\ttagsNames() {\n\t\t\treturn this.$store.state.systemtags.names\n\t\t},\n\n\t\ttagsList() {\n\t\t\treturn Object.keys(this.tagsNames)\n\t\t\t\t.map((tagName) => this.tags[this.tagsNames[tagName]])\n\t\t\t\t.filter((tag) => tag && tag.attributes.id)\n\t\t},\n\n\t\tpopularTags() {\n\t\t\treturn Object.keys(this.tagsNames)\n\t\t\t\t.filter((tagName) => (this.tags[this.tagsNames[tagName]].attributes['files-assigned']) > 50)\n\t\t\t\t.sort((a, b) => (this.tags[this.tagsNames[b]]['files-assigned']) - (this.tags[this.tagsNames[a]]['files-assigned']))\n\t\t\t\t.slice(0, 9)\n\t\t\t\t.map((tagName) => this.tags[this.tagsNames[tagName]])\n\t\t},\n\t},\n\n\tasync beforeMount() {\n\t\tawait this.fetchRootContent()\n\t},\n\n\tmethods: {\n\t\tasync fetchRootContent() {\n\t\t\t// close any potential opened viewer\n\t\t\twindow.OCA.Viewer.close()\n\n\t\t\tthis.error = null\n\n\t\t\ttry {\n\t\t\t\t// fetch content\n\t\t\t\tif (!this.tagsList.length) {\n\t\t\t\t\tthis.loading = true\n\t\t\t\t\tawait this.$store.dispatch('fetchAllTags', {\n\t\t\t\t\t\tsignal: this.abortController.signal,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error('Failed to fetch tags', { error })\n\t\t\t\tthis.error = true\n\t\t\t} finally {\n\t\t\t\t// done loading\n\t\t\t\tthis.loading = false\n\t\t\t}\n\t\t},\n\n\t\tt,\n\t},\n\n})\n</script>\n\n<style lang=\"scss\" scoped>\n.loader {\n\tmargin-top: 30vh;\n}\n\n.container {\n\tpadding-inline-start: 44px;\n\n\t> h2 {\n\t\tmargin-inline-start: 14px;\n\t\tmargin-top: 40px;\n\t}\n}\n\n.popular-tags, .tags {\n\tdisplay: flex;\n\tflex-direction: row;\n\tgap: 8px;\n\tflex-wrap: wrap;\n}\n</style>\n"],"names":["_sfc_main$1","defineComponent","RouterLink","ImageMultipleOutline","AbortControllerMixin","generateUrl","entries","t","l","_sfc_main","TagCover","NcLoadingIcon","NcEmptyContent","tagName","tag","a","b","error","logger"],"mappings":"ubAyCA,MAAAA,EAAAC,EAAA,CACA,KAAA,WAEA,WAAA,CAAA,WACAC,EACA,qBAAAC,CAAA,EAGA,OAAA,CAAAC,CAAA,EAEA,MAAA,CACA,IAAA,CACA,KAAA,OACA,SAAA,EAAA,CACA,EAGA,MAAA,CACA,MAAA,CACA,UAAA,GACA,SAAA,IAAA,CAEA,EAEA,SAAA,CACA,MAAA,CACA,OAAA,KAAA,OAAA,MAAA,WAAA,IACA,EAEA,OAAA,CACA,OAAA,KAAA,OAAA,MAAA,MAAA,KACA,EAEA,UAAA,CACA,OAAA,KAAA,UAGAC,EAAA,wBAAA,KAAA,IAAA,WAAA,kBAAA,CAAA,8BAAA,EAFA,EAGA,EAEA,OAAA,CACA,OAAA,KAAA,IAAA,WAAA,gBAAA,CACA,CAAA,EAGA,MAAA,CACA,WAAA,CACA,KAAA,IAAA,WAAA,gBAAA,GAGA,KAAA,OAAA,SAAA,gBAAA,CAAA,GAAA,KAAA,IAAA,WAAA,GAAA,OAAA,KAAA,gBAAA,OAAA,CACA,CAAA,EAGA,SAAA,CACA,KAAA,SAAA,IAAA,qBAAAC,GAAA,CACAA,EAAA,CAAA,EAAA,iBACA,KAAA,UAAA,GACA,KAAA,UAAA,WAAA,EAEA,CAAA,EACA,KAAA,SAAA,QAAA,KAAA,GAAA,CACA,EAEA,QAAA,CAAA,EACAC,EAAAC,CACA,CAEA,CAAA,6xBCrEAC,EAAAR,EAAA,CACA,KAAA,WACA,WAAA,CACA,SAAAS,EACA,cAAAC,EACA,eAAAC,CAAA,EAGA,OAAA,CAAAR,CAAA,EAEA,MAAA,CACA,MAAA,CACA,MAAA,KACA,QAAA,GACA,SAAA,EAAA,CAEA,EAEA,SAAA,CACA,OAAA,CACA,OAAA,KAAA,OAAA,MAAA,MAAA,KACA,EAEA,MAAA,CACA,OAAA,KAAA,OAAA,MAAA,WAAA,IACA,EAEA,WAAA,CACA,OAAA,KAAA,OAAA,MAAA,WAAA,KACA,EAEA,UAAA,CACA,OAAA,OAAA,KAAA,KAAA,SAAA,EACA,IAAAS,GAAA,KAAA,KAAA,KAAA,UAAAA,CAAA,CAAA,CAAA,EACA,OAAAC,GAAAA,GAAAA,EAAA,WAAA,EAAA,CACA,EAEA,aAAA,CACA,OAAA,OAAA,KAAA,KAAA,SAAA,EACA,OAAAD,GAAA,KAAA,KAAA,KAAA,UAAAA,CAAA,CAAA,EAAA,WAAA,gBAAA,EAAA,EAAA,EACA,KAAA,CAAAE,EAAAC,IAAA,KAAA,KAAA,KAAA,UAAAA,CAAA,CAAA,EAAA,gBAAA,EAAA,KAAA,KAAA,KAAA,UAAAD,CAAA,CAAA,EAAA,gBAAA,CAAA,EACA,MAAA,EAAA,CAAA,EACA,IAAAF,GAAA,KAAA,KAAA,KAAA,UAAAA,CAAA,CAAA,CAAA,CACA,CAAA,EAGA,MAAA,aAAA,CACA,MAAA,KAAA,iBAAA,CACA,EAEA,QAAA,CACA,MAAA,kBAAA,CAEA,OAAA,IAAA,OAAA,MAAA,EAEA,KAAA,MAAA,KAEA,GAAA,CAEA,KAAA,SAAA,SACA,KAAA,QAAA,GACA,MAAA,KAAA,OAAA,SAAA,eAAA,CACA,OAAA,KAAA,gBAAA,MAAA,CACA,EAEA,OAAAI,EAAA,CACAC,EAAA,MAAA,uBAAA,CAAA,MAAAD,CAAA,CAAA,EACA,KAAA,MAAA,EACA,QAAA,CAEA,KAAA,QAAA,EACA,CACA,EAAA,EAEAV,CAAA,CAGA,CAAA"}
Save File
Cancel