Join public room

Work on issue #9
This commit is contained in:
N-Pex 2020-11-19 22:48:08 +01:00
parent e7cd5db831
commit 43e876ba80
6 changed files with 92 additions and 43 deletions

11
package-lock.json generated
View file

@ -10,6 +10,7 @@
"aes-js": "^3.1.2", "aes-js": "^3.1.2",
"axios": "^0.21.0", "axios": "^0.21.0",
"core-js": "^3.6.5", "core-js": "^3.6.5",
"intersection-observer": "^0.11.0",
"json-web-key": "^0.4.0", "json-web-key": "^0.4.0",
"material-design-icons-iconfont": "^5.0.1", "material-design-icons-iconfont": "^5.0.1",
"matrix-js-sdk": "^9.0.1", "matrix-js-sdk": "^9.0.1",
@ -7410,6 +7411,11 @@
"node": ">= 0.10" "node": ">= 0.10"
} }
}, },
"node_modules/intersection-observer": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/intersection-observer/-/intersection-observer-0.11.0.tgz",
"integrity": "sha512-KZArj2QVnmdud9zTpKf279m2bbGfG+4/kn16UU0NL3pTVl52ZHiJ9IRNSsnn6jaHrL9EGLFM5eWjTx2fz/+zoQ=="
},
"node_modules/ip": { "node_modules/ip": {
"version": "1.1.5", "version": "1.1.5",
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
@ -20706,6 +20712,11 @@
"integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
"dev": true "dev": true
}, },
"intersection-observer": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/intersection-observer/-/intersection-observer-0.11.0.tgz",
"integrity": "sha512-KZArj2QVnmdud9zTpKf279m2bbGfG+4/kn16UU0NL3pTVl52ZHiJ9IRNSsnn6jaHrL9EGLFM5eWjTx2fz/+zoQ=="
},
"ip": { "ip": {
"version": "1.1.5", "version": "1.1.5",
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",

View file

@ -11,6 +11,7 @@
"aes-js": "^3.1.2", "aes-js": "^3.1.2",
"axios": "^0.21.0", "axios": "^0.21.0",
"core-js": "^3.6.5", "core-js": "^3.6.5",
"intersection-observer": "^0.11.0",
"json-web-key": "^0.4.0", "json-web-key": "^0.4.0",
"material-design-icons-iconfont": "^5.0.1", "material-design-icons-iconfont": "^5.0.1",
"matrix-js-sdk": "^9.0.1", "matrix-js-sdk": "^9.0.1",

View file

@ -7,10 +7,7 @@
v-on:scroll="onScroll" v-on:scroll="onScroll"
> >
<div v-for="event in events" :key="event.getId()"> <div v-for="event in events" :key="event.getId()">
<component <component :is="componentForEvent(event)" :room="room" :event="event" />
:is="componentForEvent(event)"
:room="room"
:event="event" />
</div> </div>
</div> </div>
@ -81,14 +78,14 @@
<script> <script>
import { TimelineWindow, EventTimeline } from "matrix-js-sdk"; import { TimelineWindow, EventTimeline } from "matrix-js-sdk";
import MessageIncomingText from './messages/MessageIncomingText'; import MessageIncomingText from "./messages/MessageIncomingText";
import MessageOutgoingText from './messages/MessageOutgoingText'; import MessageOutgoingText from "./messages/MessageOutgoingText";
import ContactJoin from './messages/ContactJoin.vue'; import ContactJoin from "./messages/ContactJoin.vue";
import ContactLeave from './messages/ContactLeave.vue'; import ContactLeave from "./messages/ContactLeave.vue";
import ContactInvited from './messages/ContactInvited.vue'; import ContactInvited from "./messages/ContactInvited.vue";
import RoomNameChanged from './messages/RoomNameChanged.vue'; import RoomNameChanged from "./messages/RoomNameChanged.vue";
import RoomTopicChanged from './messages/RoomTopicChanged.vue'; import RoomTopicChanged from "./messages/RoomTopicChanged.vue";
import RoomAvatarChanged from './messages/RoomAvatarChanged.vue'; import RoomAvatarChanged from "./messages/RoomAvatarChanged.vue";
import DebugEvent from "./messages/DebugEvent.vue"; import DebugEvent from "./messages/DebugEvent.vue";
import MessageOutgoingImage from "./messages/MessageOutgoingImage.vue"; import MessageOutgoingImage from "./messages/MessageOutgoingImage.vue";
import MessageIncomingImage from "./messages/MessageIncomingImage.vue"; import MessageIncomingImage from "./messages/MessageIncomingImage.vue";
@ -134,22 +131,25 @@ export default {
RoomAvatarChanged, RoomAvatarChanged,
DebugEvent, DebugEvent,
MessageOutgoingImage, MessageOutgoingImage,
MessageIncomingImage MessageIncomingImage,
}, },
data() { return { data() {
room: null, return {
events: [], room: null,
currentInput: "", events: [],
contactIsTyping: false, currentInput: "",
timelineWindow: null, contactIsTyping: false,
scrollPosition: null, timelineWindow: null,
currentImageInput: null, scrollPosition: null,
currentImageInputPath: null, currentImageInput: null,
currentSendOperation: null, currentImageInputPath: null,
currentSendProgress: null, currentSendOperation: null,
currentSendError: null, currentSendProgress: null,
}}, currentSendError: null,
joinRoom: null,
};
},
mounted() { mounted() {
const container = this.$refs.chatContainer; const container = this.$refs.chatContainer;
@ -157,11 +157,21 @@ export default {
this.$matrix.on("Room.timeline", this.onEvent); this.$matrix.on("Room.timeline", this.onEvent);
this.$matrix.on("RoomMember.typing", this.onUserTyping); this.$matrix.on("RoomMember.typing", this.onUserTyping);
this.$matrix.on("Matrix.initialized", this.onInitialized);
if (this.$route.params && this.$route.params.joinRoom) {
this.joinRoom = this.$route.params.joinRoom;
}
if (this.$matrix.matrixClientReady) {
this.onInitialized(this.$matrix.matrixClient);
}
}, },
destroyed() { destroyed() {
this.$matrix.off("Room.timeline", this.onEvent); this.$matrix.off("Room.timeline", this.onEvent);
this.$matrix.off("RoomMember.typing", this.onUserTyping); this.$matrix.off("RoomMember.typing", this.onUserTyping);
this.$matrix.off("Matrix.initialized", this.onInitialized);
}, },
computed: { computed: {
@ -207,40 +217,55 @@ export default {
}, },
methods: { methods: {
onInitialized(matrixClient) {
if (this.joinRoom) {
const roomId = this.joinRoom;
this.joinRoom = null;
matrixClient
.joinRoom(roomId)
.then((room) => {
this.$matrix.setCurrentRoomId(room.roomId);
})
.catch((err) => {
// TODO - handle error
console.log("Failed to join room", err);
});
}
},
componentForEvent(event) { componentForEvent(event) {
switch (event.getType()) { switch (event.getType()) {
case 'm.room.member': case "m.room.member":
if (event.event.state_key != this.myUserId) { if (event.event.state_key != this.myUserId) {
if (event.getContent().membership == 'join') { if (event.getContent().membership == "join") {
return ContactJoin; return ContactJoin;
} else if (event.getContent().membership == 'leave') { } else if (event.getContent().membership == "leave") {
return ContactLeave; return ContactLeave;
} else if (event.getContent().membership == 'invite') { } else if (event.getContent().membership == "invite") {
return ContactInvited; return ContactInvited;
} }
} }
break; break;
case 'm.room.message': case "m.room.message":
if (event.getSender() != this.myUserId) { if (event.getSender() != this.myUserId) {
if (event.getContent().msgtype == 'm.image') { if (event.getContent().msgtype == "m.image") {
return MessageIncomingImage; return MessageIncomingImage;
} }
return MessageIncomingText; return MessageIncomingText;
} else { } else {
if (event.getContent().msgtype == 'm.image') { if (event.getContent().msgtype == "m.image") {
return MessageOutgoingImage; return MessageOutgoingImage;
} }
return MessageOutgoingText; return MessageOutgoingText;
} }
case 'm.room.name': case "m.room.name":
return RoomNameChanged; return RoomNameChanged;
case 'm.room.topic': case "m.room.topic":
return RoomTopicChanged; return RoomTopicChanged;
case 'm.room.avatar': case "m.room.avatar":
return RoomAvatarChanged; return RoomAvatarChanged;
} }
return DebugEvent; return DebugEvent;

View file

@ -39,9 +39,7 @@ class Util {
.then(response => { .then(response => {
return new Promise((resolve, ignoredReject) => { return new Promise((resolve, ignoredReject) => {
var aesjs = require('aes-js'); var aesjs = require('aes-js');
//var JSONWebKey = require( 'json-web-key' );
var base64Url = require('json-web-key/lib/base64url'); var base64Url = require('json-web-key/lib/base64url');
//var tou8 = require('buffer-to-uint8array');
var key = base64Url.decode(file.key.k); var key = base64Url.decode(file.key.k);
var iv = base64Url.decode(file.iv); var iv = base64Url.decode(file.iv);
var aesCtr = new aesjs.ModeOfOperation.ctr(key, new aesjs.Counter(iv)); var aesCtr = new aesjs.ModeOfOperation.ctr(key, new aesjs.Counter(iv));
@ -52,7 +50,7 @@ class Util {
}); });
}) })
.then(bytes => { .then(bytes => {
resolve(URL.createObjectURL(new Blob([bytes.buffer], { type: 'image/png' }))); resolve(URL.createObjectURL(new Blob([bytes.buffer], { type: file.mimetype })));
}) })
.catch(err => { .catch(err => {
console.log("Download error: ", err); console.log("Download error: ", err);

View file

@ -15,6 +15,16 @@ const routes = [
path: '/login', path: '/login',
component: Login component: Login
}, },
{
path: '/join/:room?',
redirect: from => {
const room = from.hash;
if (room) {
return { name: 'Chat', params: { joinRoom: room }};
}
return '/';
}
},
] ]
const router = new VueRouter({ const router = new VueRouter({

View file

@ -21,6 +21,7 @@ export default {
data() { data() {
return { return {
matrixClient: null, matrixClient: null,
matrixClientReady: false,
rooms: [], rooms: [],
} }
}, },
@ -73,6 +74,7 @@ export default {
this.removeMatrixClientListeners(this.matrixClient); this.removeMatrixClientListeners(this.matrixClient);
this.matrixClient.stopClient(); this.matrixClient.stopClient();
this.matrixClient = null; this.matrixClient = null;
this.matrixClientReady = false;
localStorage.removeItem('user'); localStorage.removeItem('user');
} }
this.$store.commit("setCurrentRoomId", null); this.$store.commit("setCurrentRoomId", null);
@ -80,6 +82,8 @@ export default {
initClient() { initClient() {
this.reloadRooms(); this.reloadRooms();
this.matrixClientReady = true;
this.matrixClient.emit('Matrix.initialized', this.matrixClient);
}, },
async getMatrixClient(user) { async getMatrixClient(user) {
@ -179,10 +183,10 @@ export default {
}, },
getRoom(roomId) { getRoom(roomId) {
if (this.matrixClient) { // if (this.matrixClient) {
return this.matrixClient.getRoom(roomId); // return this.matrixClient.getRoom(roomId);
} // }
return null; return this.rooms.find(room => room.roomId == roomId);
}, },
on(event, handler) { on(event, handler) {