mirror of
https://github.com/kuaifan/dootask.git
synced 2026-09-16 17:06:34 +00:00
197 lines
6.5 KiB
Vue
197 lines
6.5 KiB
Vue
<template>
|
|
<div :class="`content-file ${msg.type}`">
|
|
<div class="dialog-file">
|
|
<img v-if="msg.type === 'img'" class="file-img" :style="imageStyle(msg)" :src="imageSrc(msg)" @click="viewFile"/>
|
|
<div v-else-if="isVideoFile(msg)" class="file-video" :style="imageStyle(msg)" @click="viewFile">
|
|
<img v-if="msg.thumb" :src="msg.thumb">
|
|
<video v-else :width="imageStyle(msg, 'width')" :height="imageStyle(msg, 'height')">
|
|
<source :src="msg.path" type="video/mp4">
|
|
</video>
|
|
<div class="file-play">
|
|
<div class="play-icon no-dark-content">
|
|
<i class="taskfont"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div v-else class="file-box" @click="downFile">
|
|
<img class="file-thumb" :src="msg.thumb"/>
|
|
<div class="file-info">
|
|
<div class="file-name" :title="msg.name">{{ msg.name }}</div>
|
|
<div class="file-size">{{ $A.bytesToSize(msg.size) }}</div>
|
|
</div>
|
|
<button
|
|
v-if="$Electron"
|
|
class="file-local-action"
|
|
type="button"
|
|
:title="localActionTitle"
|
|
:aria-label="localActionTitle"
|
|
:disabled="localFileStatus === 'downloading'"
|
|
@click.stop="handleLocalAction">
|
|
<LocalFileStatusIcon :status="localFileStatus"/>
|
|
</button>
|
|
</div>
|
|
<div v-if="msg.percentage" class="file-percentage">
|
|
<span :style="fileStyle(msg.percentage)"></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import LocalFileStatusIcon from "./LocalFileStatusIcon.vue";
|
|
|
|
export default {
|
|
components: {LocalFileStatusIcon},
|
|
props: {
|
|
msgId: {
|
|
type: [Number, String],
|
|
default: 0,
|
|
},
|
|
msg: Object,
|
|
},
|
|
data() {
|
|
return {
|
|
localFileStatus: 'missing',
|
|
removeDownloadListener: null,
|
|
}
|
|
},
|
|
computed: {
|
|
localActionTitle() {
|
|
return this.localFileStatus === 'available' ? this.$L('在文件夹中显示') : this.$L('下载');
|
|
},
|
|
},
|
|
watch: {
|
|
msgId() {
|
|
this.refreshLocalFileStatus();
|
|
},
|
|
},
|
|
mounted() {
|
|
if (!this.$Electron) {
|
|
return;
|
|
}
|
|
this.refreshLocalFileStatus();
|
|
this.removeDownloadListener = $A.Electron.listener('downloadItemsChanged', () => {
|
|
this.refreshLocalFileStatus();
|
|
});
|
|
},
|
|
beforeDestroy() {
|
|
if (typeof this.removeDownloadListener === 'function') {
|
|
this.removeDownloadListener();
|
|
}
|
|
},
|
|
methods: {
|
|
viewFile() {
|
|
this.$emit('viewFile');
|
|
},
|
|
downFile() {
|
|
this.$emit('downFile');
|
|
},
|
|
|
|
async refreshLocalFileStatus() {
|
|
if (!this.$Electron || !this.msgId) {
|
|
this.localFileStatus = 'missing';
|
|
return;
|
|
}
|
|
try {
|
|
const result = await $A.Electron.sendAsync('downloadManager', {
|
|
action: 'messageFileStatus',
|
|
msgId: this.msgId,
|
|
});
|
|
this.localFileStatus = result?.status || 'missing';
|
|
} catch {
|
|
this.localFileStatus = 'missing';
|
|
}
|
|
},
|
|
|
|
async handleLocalAction() {
|
|
if (this.localFileStatus === 'downloading') {
|
|
return;
|
|
}
|
|
if (this.localFileStatus === 'available') {
|
|
try {
|
|
const shown = await $A.Electron.sendAsync('downloadManager', {
|
|
action: 'showMessageFile',
|
|
msgId: this.msgId,
|
|
});
|
|
if (shown) {
|
|
return;
|
|
}
|
|
} catch {
|
|
// Refresh the action when the local file disappears or cannot be revealed.
|
|
}
|
|
this.localFileStatus = 'missing';
|
|
return;
|
|
}
|
|
|
|
this.localFileStatus = 'downloading';
|
|
this.$store.dispatch('downUrl', $A.apiUrl(`dialog/msg/download?msg_id=${this.msgId}`));
|
|
setTimeout(() => this.refreshLocalFileStatus(), 500);
|
|
},
|
|
|
|
fileStyle(percentage) {
|
|
if (percentage) {
|
|
return {
|
|
width: `${percentage}%`
|
|
};
|
|
}
|
|
return {};
|
|
},
|
|
|
|
imageStyle({width, height, thumb}, type = 'style') {
|
|
if (width && height) {
|
|
const ratioExceed = $A.imageRatioExceed(width, height, 3)
|
|
if ($A.imageRatioJudge(thumb) && ratioExceed > 0) {
|
|
if (width > height) {
|
|
width = height * ratioExceed;
|
|
} else {
|
|
height = width * ratioExceed;
|
|
}
|
|
}
|
|
let maxW = 220,
|
|
maxH = 220,
|
|
tempW = width,
|
|
tempH = height;
|
|
if (width > maxW || height > maxH) {
|
|
if (width > height) {
|
|
tempW = maxW;
|
|
tempH = height * (maxW / width);
|
|
} else {
|
|
tempW = width * (maxH / height);
|
|
tempH = maxH;
|
|
}
|
|
}
|
|
if (type === 'width') {
|
|
return tempW
|
|
}
|
|
if (type === 'height') {
|
|
return tempH
|
|
}
|
|
return {
|
|
width: tempW + 'px',
|
|
height: tempH + 'px',
|
|
};
|
|
}
|
|
if (type === 'width' || type === 'height') {
|
|
return 0
|
|
}
|
|
return {};
|
|
},
|
|
|
|
imageSrc({width, height, thumb}) {
|
|
const ratioExceed = $A.imageRatioExceed(width, height, 3)
|
|
if ($A.imageRatioJudge(thumb) && ratioExceed > 0) {
|
|
thumb = $A.thumbRestore(thumb) + `/crop/ratio:${ratioExceed},percentage:320x0`;
|
|
}
|
|
return thumb;
|
|
},
|
|
|
|
isVideoFile(msg) {
|
|
return msg.type === 'file'
|
|
&& msg.ext === 'mp4'
|
|
&& msg.width > 0
|
|
&& msg.height > 0;
|
|
},
|
|
},
|
|
}
|
|
</script>
|