summaryrefslogtreecommitdiff
path: root/src/client/components/drive-file-thumbnail.vue
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2020-01-30 04:37:25 +0900
committerGitHub <noreply@github.com>2020-01-30 04:37:25 +0900
commitf6154dc0af1a0d65819e87240f4385f9573095cb (patch)
tree699a5ca07d6727b7f8497d4769f25d6d62f94b5a /src/client/components/drive-file-thumbnail.vue
parentAdd Event activity-type support (#5785) (diff)
downloadmisskey-f6154dc0af1a0d65819e87240f4385f9573095cb.tar.gz
misskey-f6154dc0af1a0d65819e87240f4385f9573095cb.tar.bz2
misskey-f6154dc0af1a0d65819e87240f4385f9573095cb.zip
v12 (#5712)
Co-authored-by: MeiMei <30769358+mei23@users.noreply.github.com> Co-authored-by: Satsuki Yanagi <17376330+u1-liquid@users.noreply.github.com>
Diffstat (limited to 'src/client/components/drive-file-thumbnail.vue')
-rw-r--r--src/client/components/drive-file-thumbnail.vue188
1 files changed, 188 insertions, 0 deletions
diff --git a/src/client/components/drive-file-thumbnail.vue b/src/client/components/drive-file-thumbnail.vue
new file mode 100644
index 0000000000..37a884dc3d
--- /dev/null
+++ b/src/client/components/drive-file-thumbnail.vue
@@ -0,0 +1,188 @@
+<template>
+<div class="zdjebgpv" :class="{ detail }" ref="thumbnail" :style="`background-color: ${ background }`">
+ <img
+ :src="file.url"
+ :alt="file.name"
+ :title="file.name"
+ @load="onThumbnailLoaded"
+ v-if="detail && is === 'image'"/>
+ <video
+ :src="file.url"
+ ref="volumectrl"
+ preload="metadata"
+ controls
+ v-else-if="detail && is === 'video'"/>
+ <img :src="file.thumbnailUrl" alt="" @load="onThumbnailLoaded" :style="`object-fit: ${ fit }`" v-else-if="isThumbnailAvailable"/>
+ <fa :icon="faFileImage" class="icon" v-else-if="is === 'image'"/>
+ <fa :icon="faFileVideo" class="icon" v-else-if="is === 'video'"/>
+
+ <audio
+ :src="file.url"
+ ref="volumectrl"
+ preload="metadata"
+ controls
+ v-else-if="detail && is === 'audio'"/>
+ <fa :icon="faMusic" class="icon" v-else-if="is === 'audio' || is === 'midi'"/>
+
+ <fa :icon="faFileCsv" class="icon" v-else-if="is === 'csv'"/>
+ <fa :icon="faFilePdf" class="icon" v-else-if="is === 'pdf'"/>
+ <fa :icon="faFileAlt" class="icon" v-else-if="is === 'textfile'"/>
+ <fa :icon="faFileArchive" class="icon" v-else-if="is === 'archive'"/>
+ <fa :icon="faFile" class="icon" v-else/>
+
+ <fa :icon="faFilm" class="icon-sub" v-if="!detail && isThumbnailAvailable && is === 'video'"/>
+</div>
+</template>
+
+<script lang="ts">
+import Vue from 'vue';
+import {
+ faFile,
+ faFileAlt,
+ faFileImage,
+ faMusic,
+ faFileVideo,
+ faFileCsv,
+ faFilePdf,
+ faFileArchive,
+ faFilm
+ } from '@fortawesome/free-solid-svg-icons';
+
+export default Vue.extend({
+ props: {
+ file: {
+ type: Object,
+ required: true
+ },
+ fit: {
+ type: String,
+ required: false,
+ default: 'cover'
+ },
+ detail: {
+ type: Boolean,
+ required: false,
+ default: false
+ }
+ },
+ data() {
+ return {
+ isContextmenuShowing: false,
+ isDragging: false,
+
+ faFile,
+ faFileAlt,
+ faFileImage,
+ faMusic,
+ faFileVideo,
+ faFileCsv,
+ faFilePdf,
+ faFileArchive,
+ faFilm
+ };
+ },
+ computed: {
+ is(): 'image' | 'video' | 'midi' | 'audio' | 'csv' | 'pdf' | 'textfile' | 'archive' | 'unknown' {
+ if (this.file.type.startsWith('image/')) return 'image';
+ if (this.file.type.startsWith('video/')) return 'video';
+ if (this.file.type === 'audio/midi') return 'midi';
+ if (this.file.type.startsWith('audio/')) return 'audio';
+ if (this.file.type.endsWith('/csv')) return 'csv';
+ if (this.file.type.endsWith('/pdf')) return 'pdf';
+ if (this.file.type.startsWith('text/')) return 'textfile';
+ if ([
+ "application/zip",
+ "application/x-cpio",
+ "application/x-bzip",
+ "application/x-bzip2",
+ "application/java-archive",
+ "application/x-rar-compressed",
+ "application/x-tar",
+ "application/gzip",
+ "application/x-7z-compressed"
+ ].some(e => e === this.file.type)) return 'archive';
+ return 'unknown';
+ },
+ isThumbnailAvailable(): boolean {
+ return this.file.thumbnailUrl
+ ? (this.is === 'image' || this.is === 'video')
+ : false;
+ },
+ background(): string {
+ return this.file.properties.avgColor || 'transparent';
+ }
+ },
+ mounted() {
+ const audioTag = this.$refs.volumectrl as HTMLAudioElement;
+ if (audioTag) audioTag.volume = this.$store.state.device.mediaVolume;
+ },
+ methods: {
+ onThumbnailLoaded() {
+ if (this.file.properties.avgColor) {
+ this.$refs.thumbnail.style.backgroundColor = 'transparent';
+ }
+ },
+ volumechange() {
+ const audioTag = this.$refs.volumectrl as HTMLAudioElement;
+ this.$store.commit('device/set', { key: 'mediaVolume', value: audioTag.volume });
+ }
+ }
+});
+</script>
+
+<style lang="scss" scoped>
+.zdjebgpv {
+ display: flex;
+
+ > img,
+ > .icon {
+ pointer-events: none;
+ }
+
+ > .icon-sub {
+ position: absolute;
+ width: 30%;
+ height: auto;
+ margin: 0;
+ right: 4%;
+ bottom: 4%;
+ }
+
+ > * {
+ margin: auto;
+ }
+
+ &:not(.detail) {
+ > img {
+ height: 100%;
+ width: 100%;
+ object-fit: cover;
+ }
+
+ > .icon {
+ height: 65%;
+ width: 65%;
+ }
+
+ > video,
+ > audio {
+ width: 100%;
+ }
+ }
+
+ &.detail {
+ > .icon {
+ height: 100px;
+ width: 100px;
+ margin: 16px;
+ }
+
+ > *:not(.icon) {
+ max-height: 300px;
+ max-width: 100%;
+ height: 100%;
+ object-fit: contain;
+ }
+ }
+}
+</style>