diff --git a/package.json b/package.json
index c57fd22..8706b37 100644
--- a/package.json
+++ b/package.json
@@ -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"
diff --git a/public/sym/ic_attach_file_white.svg b/public/sym/ic_attach_file_white.svg
new file mode 100644
index 0000000..0029471
--- /dev/null
+++ b/public/sym/ic_attach_file_white.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/sym/ic_insert_emoticon_white.svg b/public/sym/ic_insert_emoticon_white.svg
new file mode 100644
index 0000000..438740f
--- /dev/null
+++ b/public/sym/ic_insert_emoticon_white.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/sym/ic_mic_white.svg b/public/sym/ic_mic_white.svg
new file mode 100644
index 0000000..4c29695
--- /dev/null
+++ b/public/sym/ic_mic_white.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/components/event.vue b/src/components/event.vue
index 85d9c07..aa45258 100644
--- a/src/components/event.vue
+++ b/src/components/event.vue
@@ -2,34 +2,7 @@
-
-
-
-
-
- {{event.content.body}}
-
-
-
-
- {{event.content.body}}
-
-
-
- {{event.content.body}}
-
-
unsupported message type {{event.content.msgtype}}
-
+
{{getTime(event.origin_server_ts)}}
@@ -47,10 +20,11 @@ import {parseMessage} from '@/lib/eventUtils';
import {getTime} from '@/lib/getTimeStrings';
import {getMediaUrl} from '@/lib/getMxc';
import ReplyEvent from '@/components/replyEvent';
+import EventContent from '@/components/eventContent';
export default {
name: 'message',
- components: {ReplyEvent},
+ components: {EventContent, ReplyEvent},
props: {
type: String,
event: Object,
@@ -134,32 +108,6 @@ export default {
.notice{
font-style: italic;
}
- .image{
- width: 100%;
- img{
- max-width: 100%;
- height: auto;
- max-height: 35rem;
- border-radius: 0.5rem;
- }
- }
- .video{
- width: 100%;
- video{
- max-width: 100%;
- height: auto;
- max-height: 35rem;
- border-radius: 0.5rem;
- }
- }
- .audio{
- audio{
- max-width: 100%;
- }
- }
- .italic{
- font-style: italic;
- }
}
.messageReceive{
background-color: #424141;
diff --git a/src/components/eventContent.vue b/src/components/eventContent.vue
new file mode 100644
index 0000000..80a6980
--- /dev/null
+++ b/src/components/eventContent.vue
@@ -0,0 +1,128 @@
+
+
+
+
+
+ {{content.body}}
+
+
+
+
+ {{content.body}}
+
+
+
+ {{content.body}}
+
+ unsupported message type {{content.msgtype}}
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/fileUpload.vue b/src/components/fileUpload.vue
new file mode 100644
index 0000000..5c779c8
--- /dev/null
+++ b/src/components/fileUpload.vue
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/newMessage.vue b/src/components/newMessage.vue
index 24b930d..93a8d6c 100644
--- a/src/components/newMessage.vue
+++ b/src/components/newMessage.vue
@@ -1,21 +1,47 @@
-
+
+
+
+
-
+
+
+
@@ -25,12 +51,20 @@ 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 EventContent from '@/components/eventContent';
+import SoundRecorder from '@/components/soundRecorder';
+import FileUpload from '@/components/fileUpload';
export default {
name: 'newMessage',
components: {
+ FileUpload,
+ SoundRecorder,
+ EventContent,
ReplyEvent,
- icon
+ icon,
+ VEmojiPicker
},
props: {
onResize: Function,
@@ -39,21 +73,37 @@ export default {
resetReplyTo: Function
},
methods: {
- sendMessage(){
- let content = this.event.content;
- if (!content.body.trim()) return;
- matrix.sendEvent(this.event, this.roomId, this.replyTo);
- content.body = '';
+ onSubmit(event){
+ console.log(event)
+ event.content.msgtype==='m.text'?this.sendEvent(event):this.sendMediaEvent(event);
+ },
+ async sendEvent(event){
+ if (!event.content.body.trim()) return;
+ if (this.replyTo) this.setReplyTo(this.replyTo);
+ matrix.sendEvent(new Proxy(this.event, this.eventProxyHandler), this.roomId);
+ event.content.body = '';
+ this.resetAttachment();
this.resetReplyTo();
let id = this.$refs.newMessageInput;
id.style.height = '1.25rem';
this.onResize(id.parentElement.clientHeight);
},
+ sendMediaEvent(event){
+ matrix.client.uploadContent(this.attachment.blob).then(mxc => {
+ event.content.url = mxc;
+ this.sendEvent(event);
+ });
+ },
sendTyping(timeout){
if (this.waitForSendTyping) return;
matrix.client.sendTyping(this.roomId, true, timeout+100);
setTimeout(()=>this.waitForSendTyping=false, timeout);
},
+ setReplyTo(event){
+ this.event.content['m.relates_to'] = {
+ 'm.in_reply_to': event
+ }
+ },
resizeMessageBanner(){
let id = this.$refs.newMessageInput;
id.style.height = '1.25rem';
@@ -69,6 +119,41 @@ export default {
onSelectEmoji(emoji) {
this.event.content.body += emoji.data;
},
+ getRecordingState(){
+ return this.$refs.recorder && this.$refs.recorder.isRecording
+ },
+ async setAttachment({blob, file = blob}){
+ this.attachment = {
+ msgtype: this.getMsgType(file.type),
+ mimetype: file.type,
+ url: window.URL.createObjectURL(file),
+ filename: file.name,
+ blob,
+ file
+ };
+ this.event.content = {
+ body: file.name,
+ msgtype: this.attachment.msgtype,
+ mimetype: this.attachment.mimetype,
+ filename: file.name
+ };
+ },
+ resetAttachment(){
+ if (!this.attachment) return;
+ window.URL.revokeObjectURL(this.attachment.file);
+ this.event.content = {
+ body: this.attachment?this.event.content.body.replace(this.attachment.filename, ''):'',
+ msgtype: 'm.text'
+ };
+ this.attachment = undefined;
+ },
+ getMsgType(fileType){
+ return {
+ 'image': 'm.image',
+ 'audio': 'm.audio',
+ 'video': 'm.video'
+ }[fileType.split('/', 1)[0]] || 'm.file';
+ },
parseMessage,
calcUserName
},
@@ -80,20 +165,29 @@ export default {
body: '',
msgtype: 'm.text',
'm.relates_to': {
- 'm.in_reply_to': {
- event_id: undefined
- }
+ 'm.in_reply_to': undefined
}
}
},
showEmojiPicker: false,
- waitForSendTyping: false
+ waitForSendTyping: false,
+ attachment: undefined,
+ eventProxyHandler: {
+ set: () => true,
+ get: (target, key) => {
+ if (typeof target[key] === 'object') return new Proxy(Object.assign({}, target[key]), this.eventProxyHandler);
+ return target[key];
+ }
+ }
}
+ },
+ updated() {
+ this.resizeMessageBanner();
}
}
-
\ No newline at end of file
diff --git a/src/components/popupQuestion.vue b/src/components/popupQuestion.vue
new file mode 100644
index 0000000..a643d45
--- /dev/null
+++ b/src/components/popupQuestion.vue
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/roomListElement.vue b/src/components/roomListElement.vue
index 73b481f..d2ddd6a 100644
--- a/src/components/roomListElement.vue
+++ b/src/components/roomListElement.vue
@@ -14,13 +14,13 @@
+
+
\ No newline at end of file
diff --git a/src/components/userListElement.vue b/src/components/userListElement.vue
index 0ebaa3c..831662a 100644
--- a/src/components/userListElement.vue
+++ b/src/components/userListElement.vue
@@ -15,10 +15,10 @@