summaryrefslogtreecommitdiffstats
path: root/apps/files/src/components/TemplatePreview.vue
diff options
context:
space:
mode:
Diffstat (limited to 'apps/files/src/components/TemplatePreview.vue')
-rw-r--r--apps/files/src/components/TemplatePreview.vue203
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>