Skip to content

Commit 9703a5d

Browse files
committed
(refactor) message-file child component
1 parent f95b760 commit 9703a5d

File tree

6 files changed

+227
-163
lines changed

6 files changed

+227
-163
lines changed

src/lib/Message/Message.vue

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@
9292
</format-message>
9393

9494
<message-files
95-
v-else-if="!isAudio"
95+
v-else-if="!isAudio || message.files.length > 1"
9696
:current-user-id="currentUserId"
9797
:message="message"
9898
:room-users="roomUsers"
@@ -106,20 +106,21 @@
106106
</template>
107107
</message-files>
108108

109-
<audio-player
110-
v-else-if="isAudio"
111-
:src="message.files[0].url"
112-
@update-progress-time="progressTime = $event"
113-
@hover-audio-progress="hoverAudioProgress = $event"
114-
>
115-
<template v-for="(i, name) in $scopedSlots" #[name]="data">
116-
<slot :name="name" v-bind="data" />
117-
</template>
118-
</audio-player>
109+
<template v-else>
110+
<audio-player
111+
:src="message.files[0].url"
112+
@update-progress-time="progressTime = $event"
113+
@hover-audio-progress="hoverAudioProgress = $event"
114+
>
115+
<template v-for="(i, name) in $scopedSlots" #[name]="data">
116+
<slot :name="name" v-bind="data" />
117+
</template>
118+
</audio-player>
119119

120-
<div v-if="isAudio && !message.deleted" class="vac-progress-time">
121-
{{ progressTime }}
122-
</div>
120+
<div v-if="!message.deleted" class="vac-progress-time">
121+
{{ progressTime }}
122+
</div>
123+
</template>
123124

124125
<div class="vac-text-timestamp">
125126
<div
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
.vac-message-file-container {
2+
.vac-image-loading {
3+
filter: blur(3px);
4+
}
5+
6+
.vac-image-buttons {
7+
position: absolute;
8+
width: 100%;
9+
height: 100%;
10+
border-radius: 4px;
11+
background: linear-gradient(
12+
to bottom,
13+
rgba(0, 0, 0, 0) 55%,
14+
rgba(0, 0, 0, 0.02) 60%,
15+
rgba(0, 0, 0, 0.05) 65%,
16+
rgba(0, 0, 0, 0.1) 70%,
17+
rgba(0, 0, 0, 0.2) 75%,
18+
rgba(0, 0, 0, 0.3) 80%,
19+
rgba(0, 0, 0, 0.5) 85%,
20+
rgba(0, 0, 0, 0.6) 90%,
21+
rgba(0, 0, 0, 0.7) 95%,
22+
rgba(0, 0, 0, 0.8) 100%
23+
);
24+
25+
svg {
26+
height: 26px;
27+
width: 26px;
28+
}
29+
30+
.vac-button-view,
31+
.vac-button-download {
32+
position: absolute;
33+
bottom: 6px;
34+
left: 7px;
35+
}
36+
37+
:first-child {
38+
left: 40px;
39+
}
40+
41+
.vac-button-view {
42+
max-width: 18px;
43+
bottom: 8px;
44+
}
45+
}
46+
47+
.vac-video-container {
48+
width: 350px;
49+
max-width: 100%;
50+
margin: 4px auto 5px;
51+
52+
video {
53+
border-radius: 4px;
54+
}
55+
}
56+
}
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
<template>
2+
<div class="vac-message-file-container">
3+
<div v-if="isImage" :ref="'imageRef' + index">
4+
<loader
5+
:style="{ top: `${imageResponsive.loaderTop}px` }"
6+
:show="isImageLoading"
7+
/>
8+
<div
9+
class="vac-message-image"
10+
:class="{
11+
'vac-image-loading':
12+
isImageLoading && message.senderId === currentUserId
13+
}"
14+
:style="{
15+
'background-image': `url('${
16+
isImageLoading ? file.preview || file.url : file.url
17+
}')`,
18+
'max-height': `${imageResponsive.maxHeight}px`
19+
}"
20+
>
21+
<transition name="vac-fade-image">
22+
<div v-if="imageHover && !isImageLoading" class="vac-image-buttons">
23+
<div
24+
class="vac-svg-button vac-button-view"
25+
@click.stop="openFile('preview')"
26+
>
27+
<slot name="eye-icon">
28+
<svg-icon name="eye" />
29+
</slot>
30+
</div>
31+
<div
32+
class="vac-svg-button vac-button-download"
33+
@click.stop="openFile('download')"
34+
>
35+
<slot name="document-icon">
36+
<svg-icon name="document" />
37+
</slot>
38+
</div>
39+
</div>
40+
</transition>
41+
</div>
42+
</div>
43+
44+
<div v-else-if="isVideo" class="vac-video-container">
45+
<video width="100%" height="100%" controls>
46+
<source :src="file.url" />
47+
</video>
48+
</div>
49+
</div>
50+
</template>
51+
52+
<script>
53+
import Loader from '../../../components/Loader/Loader'
54+
import SvgIcon from '../../../components/SvgIcon/SvgIcon'
55+
56+
const { isImageFile, isVideoFile } = require('../../../utils/media-file')
57+
58+
export default {
59+
name: 'MessageFile',
60+
components: { SvgIcon, Loader },
61+
62+
props: {
63+
currentUserId: { type: [String, Number], required: true },
64+
message: { type: Object, required: true },
65+
file: { type: Object, required: true },
66+
imageHover: { type: Boolean, required: true },
67+
index: { type: Number, required: true }
68+
},
69+
70+
emits: ['open-file'],
71+
72+
data() {
73+
return {
74+
imageResponsive: '',
75+
imageLoading: false
76+
}
77+
},
78+
79+
computed: {
80+
isImageLoading() {
81+
return this.file.url.indexOf('blob:http') !== -1 || this.imageLoading
82+
},
83+
isImage() {
84+
return isImageFile(this.file)
85+
},
86+
isVideo() {
87+
return isVideoFile(this.file)
88+
}
89+
},
90+
91+
watch: {
92+
file: {
93+
immediate: true,
94+
handler() {
95+
this.checkImgLoad()
96+
}
97+
}
98+
},
99+
100+
mounted() {
101+
const ref = this.$refs['imageRef' + this.index]
102+
103+
this.imageResponsive = {
104+
maxHeight: ref.clientWidth - 18,
105+
loaderTop: ref.clientWidth / 2
106+
}
107+
},
108+
109+
methods: {
110+
checkImgLoad() {
111+
if (!isImageFile(this.file)) return
112+
this.imageLoading = true
113+
const image = new Image()
114+
image.src = this.file.url
115+
image.addEventListener('load', () => (this.imageLoading = false))
116+
},
117+
openFile(action) {
118+
this.$emit('open-file', { file: this.file, action })
119+
}
120+
}
121+
}
122+
</script>

src/lib/Message/MessageFiles/MessageFiles.scss

Lines changed: 1 addition & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,6 @@
11
.vac-image-container {
2-
.vac-image-loading {
3-
filter: blur(3px);
4-
}
5-
6-
.vac-image-buttons {
7-
position: absolute;
8-
width: 100%;
9-
height: 100%;
10-
border-radius: 4px;
11-
background: linear-gradient(
12-
to bottom,
13-
rgba(0, 0, 0, 0) 55%,
14-
rgba(0, 0, 0, 0.02) 60%,
15-
rgba(0, 0, 0, 0.05) 65%,
16-
rgba(0, 0, 0, 0.1) 70%,
17-
rgba(0, 0, 0, 0.2) 75%,
18-
rgba(0, 0, 0, 0.3) 80%,
19-
rgba(0, 0, 0, 0.5) 85%,
20-
rgba(0, 0, 0, 0.6) 90%,
21-
rgba(0, 0, 0, 0.7) 95%,
22-
rgba(0, 0, 0, 0.8) 100%
23-
);
24-
25-
svg {
26-
height: 26px;
27-
width: 26px;
28-
}
29-
30-
.vac-button-view,
31-
.vac-button-download {
32-
position: absolute;
33-
bottom: 6px;
34-
left: 7px;
35-
}
36-
37-
:first-child {
38-
left: 40px;
39-
}
40-
41-
.vac-button-view {
42-
max-width: 18px;
43-
bottom: 8px;
44-
}
45-
}
46-
47-
.vac-video-container {
48-
width: 350px;
49-
max-width: 100%;
50-
margin: 4px auto 5px;
51-
52-
video {
53-
border-radius: 4px;
54-
}
55-
}
56-
572
.vac-file-message {
3+
display: flex;
584
height: 60px;
595
width: 60px;
606
display: flex;

0 commit comments

Comments
 (0)