Update ThumbnailView.vue

This commit is contained in:
N-Pex 2025-06-09 09:44:49 +02:00
parent 842c87dc96
commit 77eebafb79

View file

@ -1,113 +1,124 @@
<template> <template>
<div ref="thumbnailRef"> <div ref="thumbnailRef">
<v-responsive v-if="item.event.getContent().msgtype == 'm.video' && item.src" :class="{'thumbnail-item': true, 'preview': previewOnly}"> <v-responsive
<video :src="item.src" :controls="!previewOnly" class="w-100 h-100"> v-if="item.event.getContent().msgtype == 'm.video' && item.src"
{{ $t('fallbacks.video_file') }} :class="{ 'thumbnail-item': true, preview: previewOnly }"
</video> >
</v-responsive> <video :src="item.src" :controls="!previewOnly" class="w-100 h-100">
<v-img v-else-if="item.event.getContent().msgtype == 'm.image' && item.src" :aspect-ratio="previewOnly ? (16 / 9) : undefined" :class="{'thumbnail-item': true, 'preview': previewOnly}" :src="item.src" :contain="!previewOnly" :cover="previewOnly" /> {{ $t("fallbacks.video_file") }}
<div v-else :class="{'thumbnail-item': true, 'preview': previewOnly, 'file-item': true}" > </video>
<v-icon :class="fileTypeIconClass">{{ fileTypeIcon }}</v-icon> </v-responsive>
<div class="file-name">{{ $sanitize(fileName) }}</div> <v-img
<div class="file-size">{{ fileSize }}</div> v-else-if="item.event.getContent().msgtype == 'm.image' && item.src"
</div> :aspect-ratio="previewOnly ? 16 / 9 : undefined"
:class="{ 'thumbnail-item': true, preview: previewOnly }"
:src="item.src"
:contain="!previewOnly"
:cover="previewOnly"
/>
<div v-else :class="{ 'thumbnail-item': true, preview: previewOnly, 'file-item': true }">
<v-icon :class="fileTypeIconClass">{{ fileTypeIcon }}</v-icon>
<div class="file-name">{{ $sanitize(fileName) }}</div>
<div class="file-size">{{ fileSize }}</div>
</div> </div>
</div>
</template> </template>
<script> <script lang="ts">
import util from "../../plugins/utils"; import util from "../../plugins/utils";
import { defineComponent } from "vue";
import type { PropType } from 'vue'
import { EventAttachment } from "../../models/eventAttachment";
export default { export default defineComponent({
props: { props: {
/** /**
* Item is an object of { event: MXEvent, src: URL } * Item is an object of { event: MXEvent, src: URL }
*/ */
item: { item: {
type: Object, type: Object as PropType<EventAttachment>,
default: function () { default: function () {
return {} return {};
} },
},
previewOnly: {
type: Boolean,
default: function() {
return false;
}
},
}, },
computed: { previewOnly: {
fileTypeIcon() { type: Boolean,
if (util.isFileTypeAPK(this.item.event)) { default: function () {
if (this.item.event.isChannelMessage) { return false;
return "$vuetify.icons.ic_channel_apk"; },
} },
return "$vuetify.icons.ic_apk"; },
} else if (util.isFileTypeIPA(this.item.event)) { computed: {
return "$vuetify.icons.ic_ipa"; fileTypeIcon() {
} else if (util.isFileTypePDF(this.item.event)) { if (util.isFileTypeAPK(this.item.event)) {
if (this.item.event.isChannelMessage) { if (this.item.event.isChannelMessage) {
return "$vuetify.icons.ic_channel_pdf"; return "$vuetify.icons.ic_channel_apk";
}
return "$vuetify.icons.ic_pdf";
} else if (util.isFileTypeZip(this.item.event)) {
return "$vuetify.icons.ic_zip";
}
return "description"
},
fileTypeIconClass() {
if (util.isFileTypeZip(this.item.event)) {
return "zip";
}
return undefined;
},
fileName() {
return util.getFileName(this.item.event);
},
fileSize() {
return util.getFileSizeFormatted(this.item.event);
} }
return "$vuetify.icons.ic_apk";
} else if (util.isFileTypeIPA(this.item.event)) {
return "$vuetify.icons.ic_ipa";
} else if (util.isFileTypePDF(this.item.event)) {
if (this.item.event.isChannelMessage) {
return "$vuetify.icons.ic_channel_pdf";
}
return "$vuetify.icons.ic_pdf";
} else if (util.isFileTypeZip(this.item.event)) {
return "$vuetify.icons.ic_zip";
}
return "description";
}, },
methods: { fileTypeIconClass() {
// listen for custom hammerJs singletab click to differentiate it from double click(heart animation). if (util.isFileTypeZip(this.item.event)) {
initThumbnailHammerJs(element) { return "zip";
const hammerInstance = util.singleOrDoubleTabRecognizer(element) }
return undefined;
},
fileName() {
return util.getFileName(this.item.event);
},
fileSize() {
return util.getFileSizeFormatted(this.item.event);
},
},
methods: {
// listen for custom hammerJs singletab click to differentiate it from double click(heart animation).
initThumbnailHammerJs(element: any) {
const hammerInstance = util.singleOrDoubleTabRecognizer(element);
hammerInstance.on("singletap doubletap", (ev) => { hammerInstance.on("singletap doubletap", (ev: any) => {
if(ev.type === 'singletap') { if (ev.type === "singletap") {
this.$emit('itemclick', { item: this.item }) this.$emit("itemclick", { item: this.item });
}
});
} }
});
}, },
mounted() { },
if(this.$refs.thumbnailRef) { mounted() {
this.initThumbnailHammerJs(this.$refs.thumbnailRef); if (this.$refs.thumbnailRef) {
} this.initThumbnailHammerJs(this.$refs.thumbnailRef);
}, }
} },
});
</script> </script>
<style lang="scss"> <style lang="scss">
@use "@/assets/css/chat.scss" as *; @use "@/assets/css/chat.scss" as *;
.thumbnail-item { .thumbnail-item {
width: 100%; width: 100%;
height: 100%; height: 100%;
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
.file-item { .file-item {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-size: 0.6rem; font-size: 0.6rem;
flex-direction: column; flex-direction: column;
padding: 20px; padding: 20px;
.v-icon { .v-icon {
margin-bottom: 10px; margin-bottom: 10px;
color: currentColor; color: currentColor;
} }
} }
</style> </style>