diff options
Diffstat (limited to 'apps/files/src/components/TemplatePreview.vue')
-rw-r--r-- | apps/files/src/components/TemplatePreview.vue | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/apps/files/src/components/TemplatePreview.vue b/apps/files/src/components/TemplatePreview.vue new file mode 100644 index 00000000000..538e1bcff7b --- /dev/null +++ b/apps/files/src/components/TemplatePreview.vue @@ -0,0 +1,203 @@ +<!-- + - @copyright Copyright (c) 2020 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/>. + - + --> + +<template> + <li class="template-picker__item"> + <input :id="id" + :checked="checked" + type="radio" + class="radio" + name="template-picker" + @change="onCheck"> + + <label :for="id" class="template-picker__label"> + <div class="template-picker__preview"> + <img class="template-picker__image" + :class="failedPreview ? 'template-picker__image--failed' : ''" + :src="realPreviewUrl" + alt="" + draggable="false" + @error="onFailure"> + </div> + + <span class="template-picker__title"> + {{ basename }} + </span> + </label> + </li> +</template> + +<script> +import { generateUrl } from '@nextcloud/router' +import { encodeFilePath } from '../utils/fileUtils' +import { getToken, isPublic } from '../utils/davUtils' + +// preview width generation +const previewWidth = 256 + +export default { + name: 'TemplatePreview', + inheritAttrs: false, + + props: { + basename: { + type: String, + required: true, + }, + checked: { + type: Boolean, + default: false, + }, + fileid: { + type: [String, Number], + required: true, + }, + filename: { + type: String, + required: true, + }, + previewUrl: { + type: String, + default: null, + }, + hasPreview: { + type: Boolean, + default: true, + }, + mime: { + type: String, + required: true, + }, + ratio: { + type: Number, + default: null, + }, + }, + + data() { + return { + failedPreview: false, + } + }, + + computed: { + id() { + return `template-picker-${this.fileid}` + }, + + realPreviewUrl() { + // If original preview failed, fallback to mime icon + if (this.failedPreview && this.mimeIcon) { + return generateUrl(this.mimeIcon) + } + + if (this.previewUrl) { + return this.previewUrl + } + // TODO: find a nicer standard way of doing this? + if (isPublic()) { + return generateUrl(`/apps/files_sharing/publicpreview/${getToken()}?fileId=${this.fileid}&file=${encodeFilePath(this.filename)}&x=${previewWidth}&y=${previewWidth}&a=1`) + } + return generateUrl(`/core/preview?fileId=${this.fileid}&x=${previewWidth}&y=${previewWidth}&a=1`) + }, + + mimeIcon() { + return OC.MimeType.getIconUrl(this.mime) + }, + }, + + methods: { + onCheck() { + this.$emit('check', this.fileid) + }, + onFailure() { + this.failedPreview = true + }, + }, +} +</script> + +<style lang="scss" scoped> + +.template-picker { + &__item { + display: flex; + } + + &__label { + display: flex; + // Align in the middle of the grid + align-items: center; + flex: 1 1; + flex-direction: column; + margin: var(--margin); + + &, * { + cursor: pointer; + user-select: none; + } + + &::before { + display: none !important; + } + } + + &__preview { + display: flex; + overflow: hidden; + // Stretch so all entries are the same width + flex: 1 1; + width: var(--width); + min-height: var(--width); + max-height: var(--height); + padding: var(--margin); + border: var(--border) solid var(--color-border); + border-radius: var(--border-radius-large); + + input:checked + label > & { + border-color: var(--color-primary); + } + } + + &__image { + max-width: 100%; + background-color: var(--color-main-background); + + &--failed { + width: calc(var(--margin) * 8); + // Center mime icon + margin: auto; + background-color: transparent !important; + } + } + + &__title { + overflow: hidden; + // also count preview border + max-width: calc(var(--width) + 2*2px); + padding: var(--margin); + white-space: nowrap; + text-overflow: ellipsis; + } +} + +</style> |