Skip to content

Commit e647f3d

Browse files
committed
(feature) add textarea video preview
1 parent 292de8b commit e647f3d

File tree

1 file changed

+80
-28
lines changed

1 file changed

+80
-28
lines changed

src/ChatWindow/Room.vue

Lines changed: 80 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,10 @@
233233
class="vac-box-footer"
234234
:class="{ 'vac-app-box-shadow': filteredUsersTag.length }"
235235
>
236-
<div class="vac-icon-textarea-left" v-if="showAudio && !imageFile">
236+
<div
237+
class="vac-icon-textarea-left"
238+
v-if="showAudio && !imageFile && !videoFile"
239+
>
237240
<div class="vac-svg-button" @click="recordAudio">
238241
<slot
239242
v-if="recorder.state === 'recording'"
@@ -247,14 +250,29 @@
247250
</div>
248251
</div>
249252

250-
<div class="vac-image-container" v-if="imageFile">
251-
<div class="vac-svg-button vac-icon-image" @click="resetImageFile">
253+
<div v-if="imageFile" class="vac-media-container">
254+
<div class="vac-svg-button vac-icon-media" @click="resetMediaFile">
252255
<slot name="image-close-icon">
253256
<svg-icon name="close" param="image" />
254257
</slot>
255258
</div>
256-
<div class="vac-image-file">
257-
<img ref="imageFile" :src="imageFile" @load="onImgLoad" />
259+
<div class="vac-media-file">
260+
<img ref="mediaFile" :src="imageFile" @load="onMediaLoad" />
261+
</div>
262+
</div>
263+
264+
<div v-else-if="videoFile" class="vac-media-container">
265+
<div class="vac-svg-button vac-icon-media" @click="resetMediaFile">
266+
<slot name="image-close-icon">
267+
<svg-icon name="close" param="image" />
268+
</slot>
269+
</div>
270+
<div ref="mediaFile" class="vac-media-file">
271+
<video width="100%" height="100%" controls>
272+
<source :src="videoFile" type="video/mp4" />
273+
<source :src="videoFile" type="video/ogg" />
274+
<source :src="videoFile" type="video/webm" />
275+
</video>
258276
</div>
259277
</div>
260278

@@ -281,17 +299,17 @@
281299
</div>
282300

283301
<textarea
284-
v-show="!file || imageFile"
302+
v-show="!file || imageFile || videoFile"
285303
ref="roomTextarea"
286304
:placeholder="textMessages.TYPE_MESSAGE"
287305
class="vac-textarea"
288306
:class="{
289307
'vac-textarea-outline': editedMessage._id
290308
}"
291309
:style="{
292-
'min-height': `${imageDimensions ? imageDimensions.height : 20}px`,
310+
'min-height': `${mediaDimensions ? mediaDimensions.height : 20}px`,
293311
'padding-left': `${
294-
imageDimensions ? imageDimensions.width - 10 : 12
312+
mediaDimensions ? mediaDimensions.width - 10 : 12
295313
}px`
296314
}"
297315
v-model="message"
@@ -312,7 +330,7 @@
312330
</div>
313331

314332
<emoji-picker
315-
v-if="showEmojis && (!file || imageFile)"
333+
v-if="showEmojis && (!file || imageFile || videoFile)"
316334
:emoji-opened="emojiOpened"
317335
:position-top="true"
318336
@add-emoji="addEmoji"
@@ -438,7 +456,8 @@ export default {
438456
loadingMoreMessages: false,
439457
file: null,
440458
imageFile: null,
441-
imageDimensions: null,
459+
videoFile: null,
460+
mediaDimensions: null,
442461
menuOpened: false,
443462
emojiOpened: false,
444463
hideOptions: true,
@@ -679,13 +698,13 @@ export default {
679698
this.filteredUsersTag = []
680699
this.textareaCursorPosition = null
681700
},
682-
onImgLoad() {
683-
let height = this.$refs.imageFile.height
701+
onMediaLoad() {
702+
let height = this.$refs.mediaFile.clientHeight
684703
if (height < 30) height = 30
685704
686-
this.imageDimensions = {
687-
height: this.$refs.imageFile.height - 10,
688-
width: this.$refs.imageFile.width + 26
705+
this.mediaDimensions = {
706+
height: this.$refs.mediaFile.clientHeight - 10,
707+
width: this.$refs.mediaFile.clientWidth + 26
689708
}
690709
},
691710
async recordAudio() {
@@ -778,15 +797,17 @@ export default {
778797
this.editedMessage = {}
779798
this.messageReply = null
780799
this.file = null
781-
this.imageDimensions = null
800+
this.mediaDimensions = null
782801
this.imageFile = null
802+
this.videoFile = null
783803
this.emojiOpened = false
784804
this.preventKeyboardFromClosing()
785805
setTimeout(() => this.focusTextarea(disableMobileFocus), 0)
786806
},
787-
resetImageFile() {
788-
this.imageDimensions = null
807+
resetMediaFile() {
808+
this.mediaDimensions = null
789809
this.imageFile = null
810+
this.videoFile = null
790811
this.editedMessage.file = null
791812
this.file = null
792813
this.focusTextarea()
@@ -880,7 +901,14 @@ export default {
880901
this.resetMessage()
881902
this.editedMessage = { ...message }
882903
this.file = message.file
883-
if (this.isImageCheck(this.file)) this.imageFile = message.file.url
904+
905+
if (this.isImageCheck(this.file)) {
906+
this.imageFile = message.file.url
907+
} else if (this.isVideoCheck(this.file)) {
908+
this.videoFile = message.file.url
909+
setTimeout(() => this.onMediaLoad(), 50)
910+
}
911+
884912
this.message = message.content
885913
886914
setTimeout(() => this.resizeTextarea(), 0)
@@ -920,7 +948,7 @@ export default {
920948
this.$refs.file.click()
921949
},
922950
async onFileChange(files) {
923-
this.resetImageFile()
951+
this.resetMediaFile()
924952
const file = files[0]
925953
const fileURL = URL.createObjectURL(file)
926954
const blobFile = await fetch(fileURL).then(res => res.blob())
@@ -934,15 +962,28 @@ export default {
934962
extension: file.name.substring(typeIndex + 1),
935963
localUrl: fileURL
936964
}
937-
if (this.isImageCheck(this.file)) this.imageFile = fileURL
938-
else this.message = file.name
965+
966+
if (this.isImageCheck(this.file)) {
967+
this.imageFile = fileURL
968+
} else if (this.isVideoCheck(this.file)) {
969+
this.videoFile = fileURL
970+
setTimeout(() => this.onMediaLoad(), 50)
971+
} else {
972+
this.message = file.name
973+
}
939974
},
940975
isImageCheck(file) {
941976
if (!file) return
942977
const imageTypes = IMAGE_TYPES
943978
const { type } = file
944979
return imageTypes.some(t => type.toLowerCase().includes(t))
945980
},
981+
isVideoCheck(file) {
982+
if (!file) return
983+
const videoTypes = ['video/mp4', 'video/ogg', 'video/webm']
984+
const { type } = file
985+
return videoTypes.some(t => type.toLowerCase().includes(t))
986+
},
946987
openFile({ message, action }) {
947988
this.$emit('open-file', { message, action })
948989
},
@@ -1202,6 +1243,7 @@ export default {
12021243
.vac-image-reply {
12031244
max-height: 100px;
12041245
margin-right: 10px;
1246+
border-radius: 4px;
12051247
}
12061248
}
12071249
@@ -1271,14 +1313,14 @@ export default {
12711313
}
12721314
}
12731315
1274-
.vac-image-container {
1316+
.vac-media-container {
12751317
position: absolute;
12761318
max-width: 25%;
12771319
left: 16px;
12781320
top: 18px;
12791321
}
12801322
1281-
.vac-image-file {
1323+
.vac-media-file {
12821324
display: flex;
12831325
justify-content: center;
12841326
flex-direction: column;
@@ -1290,9 +1332,16 @@ export default {
12901332
max-width: 150px;
12911333
max-height: 100%;
12921334
}
1335+
1336+
video {
1337+
border-radius: 15px;
1338+
width: 100%;
1339+
max-width: 250px;
1340+
max-height: 100%;
1341+
}
12931342
}
12941343
1295-
.vac-icon-image {
1344+
.vac-icon-media {
12961345
position: absolute;
12971346
top: 6px;
12981347
left: 6px;
@@ -1433,13 +1482,16 @@ export default {
14331482
}
14341483
}
14351484
1436-
.vac-image-container {
1485+
.vac-media-container {
14371486
top: 10px;
14381487
left: 10px;
14391488
}
14401489
1441-
.vac-image-file img {
1442-
transform: scale(0.97);
1490+
.vac-media-file {
1491+
img,
1492+
video {
1493+
transform: scale(0.97);
1494+
}
14431495
}
14441496
14451497
.vac-room-footer {

0 commit comments

Comments
 (0)