add emojiPicker and microphone

dev
adb 3 years ago
parent d3031a1e70
commit fb707fcde3

@ -34,6 +34,7 @@
"eslint": "^6.7.2",
"eslint-plugin-vue": "^7.5.0",
"node-sass": "^5.0.0",
"recorder-js": "*",
"sass-loader": "^10.1.1",
"vue-router": "^3.4.9",
"vue-template-compiler": "^2.6.11"

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#FFFFFF"><path d="M0 0h24v24H0z" fill="none"/><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm3.5-9c.83 0 1.5-.67 1.5-1.5S16.33 8 15.5 8 14 8.67 14 9.5s.67 1.5 1.5 1.5zm-7 0c.83 0 1.5-.67 1.5-1.5S9.33 8 8.5 8 7 8.67 7 9.5 7.67 11 8.5 11zm3.5 6.5c2.33 0 4.31-1.46 5.11-3.5H6.89c.8 2.04 2.78 3.5 5.11 3.5z"/></svg>

After

Width:  |  Height:  |  Size: 510 B

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#FFFFFF"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 14c1.66 0 2.99-1.34 2.99-3L15 5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm5.3-3c0 3-2.54 5.1-5.3 5.1S6.7 14 6.7 11H5c0 3.41 2.72 6.23 6 6.72V21h2v-3.28c3.28-.48 6-3.3 6-6.72h-1.7z"/></svg>

After

Width:  |  Height:  |  Size: 348 B

@ -1,22 +1,57 @@
<template>
<div class="newMessageBanner" ref="newMessageBanner">
<reply-event v-if="replyTo" :event="replyTo" @click.native="resetReplyTo()"/>
<form v-on:submit.prevent="sendMessage()">
<textarea
@keyup.enter.exact="sendMessage()"
@input="resizeMessageBanner(); sendTyping(2000);"
v-model="event.content.body"
ref="newMessageInput" class="newMessageInput"
rows="1" placeholder="type a message ..."
/>
<div class="newMessageBanner" ref="newMessageBanner">
<reply-event v-if="replyTo" :event="replyTo" @click.native="resetReplyTo()"/>
<form v-on:submit.prevent="sendMessage()">
<textarea
@keyup.enter.exact="sendMessage()"
@input="resizeMessageBanner(); sendTyping(2000);"
v-model="event.content.body"
ref="newMessageInput" class="newMessageInput"
rows="1" placeholder="type a message ..."
/>
<icon
v-if="event.content.body && !isRecording"
type="submit"
title="press enter to submit"
class="sendMessageBtn"
ic="./sym/ic_send_white.svg"
/>
<div v-else class="recorder">
<icon
v-if="!isRecording"
title="record voice"
class="recordBtn start"
ic="./sym/ic_mic_white.svg"
@click.native="startRecording()"
ref="startRecord"
/>
<div v-else class="voiceMeterContainer">
<div class="voiceMeter" ref="voiceMeter"></div>
<icon
title="record voice"
class="recordBtn stop"
ic="./sym/ic_mic_white.svg"
@click.native="stopRecording()"
ref="stopRecord"
/>
</div>
</div>
</form>
<icon
type="submit"
title="press enter to submit"
class="sendMessageBtn"
ic="./sym/ic_send_white.svg"
title="toggle emoji"
class="emojiToggle"
ic="./sym/ic_insert_emoticon_white.svg"
@click.native="toggleEmojiPicker()"
/>
</form>
</div>
<v-emoji-picker
v-if="showEmojiPicker"
class="emojiPicker"
@select="onSelectEmoji"
:dark="true"
:continuousList="true"
/>
</div>
</template>
<script>
@ -25,12 +60,16 @@ import {matrix} from '@/main.js';
import {parseMessage} from '@/lib/eventUtils';
import {calcUserName} from '@/lib/matrixUtils';
import ReplyEvent from '@/components/replyEvent';
import {VEmojiPicker} from 'v-emoji-picker';
import Recorder from 'recorder-js';
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
export default {
name: 'newMessage',
components: {
ReplyEvent,
icon
icon,
VEmojiPicker
},
props: {
onResize: Function,
@ -69,6 +108,26 @@ export default {
onSelectEmoji(emoji) {
this.event.content.body += emoji.data;
},
startRecording(){
navigator.mediaDevices.getUserMedia({audio: true})
.then(stream => {
this.recorder.init(stream);
this.recorder.start().then(()=>this.isRecording=true);
})
.catch(err => console.log('unable to get stream', err));
},
stopRecording(){
this.recorder.stop()
.then(({blob}) => {
this.recBlob = blob;
this.isRecording=false;
});
},
setVoiceMeter(value){
if (!this.$refs.stopRecord) return;
this.$refs.voiceMeter.style.height = `calc(3rem + ${value/4}px`;
this.$refs.voiceMeter.style.width = `calc(3rem + ${value/4}px`;
},
parseMessage,
calcUserName
},
@ -87,7 +146,12 @@ export default {
}
},
showEmojiPicker: false,
waitForSendTyping: false
waitForSendTyping: false,
recorder: new Recorder(audioContext, {
onAnalysed: data => this.setVoiceMeter(data.lineTo)
}),
isRecording: false,
recBlob: undefined
}
}
}
@ -109,7 +173,7 @@ export default {
margin-top: 1.25rem;
margin-bottom: 0.75rem;
padding: 0;
left: 1rem;
left: 3rem;
min-height: 1.5rem;
max-height: 10rem;
width: calc(100% - 7rem);
@ -144,4 +208,58 @@ export default {
.username{
font-weight: bold;
}
.emojiPicker{
position: absolute;
bottom: calc(100% + 0.25rem);
left: 0.25rem;
z-index: 10;
max-width: calc(100% - 0.5rem - 2px);
}
.emojiToggle{
position: absolute;
left: 0.25rem;
bottom: 0.5rem;
background-color: unset;
height: 2.5rem;
width: 2.5rem;
box-shadow: none;
}
.recordBtn{
position: absolute;
right: 1rem;
bottom: 0.25rem;
background-color: #1d1d1d;
border-radius: 50%;
}
.recordBtn.stop{
right: 0;
bottom: 0;
background-color: #c63e3e;
box-shadow: none;
}
.voiceMeter{
position: absolute;
background-color: #fff;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
border-radius: 50%;
box-shadow: 3px 3px 10px #111;
}
.voiceMeterContainer{
position: absolute;
height: 3rem;
width: 3rem;
bottom: 0.25rem;
right: 1rem;
}
.recorder{
position: absolute;
height: 100%;
width: 8rem;
bottom: 0;
right: 0;
border-radius: 0 1rem 0 0;
overflow: hidden;
}
</style>
Loading…
Cancel
Save